UIButton的标题颜色在突出显示/选中时不会改变,但背景颜色会改变

时间:2013-10-06 02:03:59

标签: ios objective-c uibutton

这是一个非常奇怪的过程。

我有一个UIButtons的IBOutletCollection。我遍历集合并像这样创建它们(从displayHourButtons调用viewWillAppear):

- (void)displayHourButtons
{
    // Counter
    NSUInteger b = 0;

    // Set attributes
    UIFont *btnFont = [UIFont fontWithName:@"Metric-Semibold" size:13.0];
    UIColor *btnTextColor = [UIColor colorWithRed:(147/255.0f) green:(147/255.0f) blue:(147/255.0f) alpha:1.0];
    NSNumber *btnTracking = [NSNumber numberWithFloat:0.25];
    NSMutableParagraphStyle *btnStyle = [[NSMutableParagraphStyle alloc] init];
    [btnStyle setLineSpacing:2.0];

    NSDictionary *btnAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
                              btnFont, NSFontAttributeName,
                              btnTextColor, NSForegroundColorAttributeName,
                              btnTracking, NSKernAttributeName, nil];

    // CREATE THE BUTTONS
    for (UIButton *hourButton in hourButtons) {
            // I'm using the attributed string for something else
            // later in development that I haven't got to yet. 
            // I simplified the string for this example's sake.
        NSString *btnTitleText = [NSString stringWithFormat:@"Button %lu", (unsigned long)b];

        NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc]
                                                     initWithString:btnTitleText
                                                     attributes:btnAttrs];

        [attributedText addAttribute:NSParagraphStyleAttributeName
                               value:btnStyle
                               range:NSMakeRange(0, btnTitleText.length)];


        CALayer *btnLayer = [hourButton layer];
        [btnLayer setMasksToBounds:YES];
        [btnLayer setCornerRadius:19.0f];
        [hourButton setTag:b];
        [hourButton setContentEdgeInsets:UIEdgeInsetsMake(5.0, 1.0, 0.0, 0.0)];
        [hourButton setAttributedTitle:attributedText forState:UIControlStateNormal];
        [hourButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
        [hourButton setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];
        hourButton.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
        [hourButton addTarget:self action:@selector(showHour:) forControlEvents:UIControlEventTouchUpInside]; 

        b++;
    }
}

单击其中一个按钮时,将根据操作showHour:调用:

- (IBAction)showHour:(id)sender
{
    [self.hourButtons enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UIButton *button = (UIButton *)obj;

        if (button != sender && button.enabled) {
                // This is applied. I know because I tested it with redColor
            [button setBackgroundColor:[UIColor clearColor]];

            // Doesn't change, stays the gray set initially
            [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        }
        else {
                // This is applied
            [button setBackgroundColor:[UIColor colorWithRed:(169/255.0f) green:(234/255.0f) blue:(255/255.0f) alpha:1.0]];

            // This is not
            [button setTitleColor:[UIColor whiteColor] forState:(UIControlStateNormal | UIControlStateSelected | UIControlStateHighlighted)];
        }
    }];

    // displayHour uses the tag to change labels, images, etc.
    [self displayHour:(long int)[sender tag]];
}

我尝试了各种疯狂的事情让UIImage处于选定的状态,但没有任何效果。这个enumerateObjects交易是唯一有效的。这就是为什么我说这是一个奇怪的过程。我猜按钮无法无限期保持活跃状态​​?

无论如何,我的问题:标题颜色没有变化的原因有哪些?只是背景?我怀疑它与最初未设置的背景有关,但我无法解释原因。

谢谢!

已更新

Per @Timothy Moose的回答,下面是更新的代码。

- (IBAction)showHour:(id)sender
{   
    [self.hourButtons enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UIButton *button = (UIButton *)obj;

        // Grab the mutable string from the button and make a mutable copy
        NSMutableAttributedString *attributedText = [[button attributedTitleForState:UIControlStateNormal] mutableCopy];

        // Shared attribute styles
        UIFont *btnFont = [UIFont fontWithName:@"Metric-Semibold" size:14.0];
        NSNumber *btnTracking = [NSNumber numberWithFloat:0.25];
        NSMutableParagraphStyle *btnStyle = [[NSMutableParagraphStyle alloc] init];
        [btnStyle setLineSpacing:2.0];

        // Since we can't set a color directly on a Attributed string we have
        // to make a new attributed string.
        if (button != sender && button.enabled) {
            // Return to the default color
            UIColor *btnTextColor = [UIColor colorWithRed:(147/255.0f) green:(147/255.0f) blue:(147/255.0f) alpha:1.0];

            // Set up attributes
            NSDictionary *btnAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
                                      btnFont, NSFontAttributeName,
                                      btnTextColor, NSForegroundColorAttributeName,
                                      btnTracking, NSKernAttributeName, nil];

            // Reapply the default color (for the one button that was changed to white)
            [attributedText setAttributes:btnAttrs
                                    range:NSMakeRange(0, attributedText.length)];

            // Add line-height
            [attributedText addAttribute:NSParagraphStyleAttributeName
                                   value:btnStyle
                                   range:NSMakeRange(0, attributedText.length)];

            // Reset default attributes
            [button setBackgroundColor:[UIColor clearColor]];
            [button setAttributedTitle:attributedText forState:UIControlStateNormal];
        }
        else {
            // Our new white color for the active button
            UIColor *btnTextColor = [UIColor whiteColor];

            // Set up attributes
            NSDictionary *btnAttrs = [NSDictionary dictionaryWithObjectsAndKeys:
                                      btnFont, NSFontAttributeName,
                                      btnTextColor, NSForegroundColorAttributeName,
                                      btnTracking, NSKernAttributeName, nil];

            // Apply our new white color
            [attributedText setAttributes:btnAttrs
                                    range:NSMakeRange(0, attributedText.length)];

            // Add line-height
            [attributedText addAttribute:NSParagraphStyleAttributeName
                                   value:btnStyle
                                   range:NSMakeRange(0, attributedText.length)];

            // Add new attributes for active button
            [button setBackgroundColor:[UIColor colorWithRed:(169/255.0f) green:(234/255.0f) blue:(255/255.0f) alpha:1.0]];
            [button setAttributedTitle:attributedText forState:UIControlStateNormal];
        }
    }];

    [self displayHour:(long int)[sender tag]];
}

6 个答案:

答案 0 :(得分:18)

同样非常重要的是不要在系统样式上使用按钮,只需将其置于自定义... 这是针对类似的问题,而不是针对这个特定的问题。

答案 1 :(得分:17)

当标题是属性字符串时,

setTitleColor没有任何效果。在将所需颜色应用于属性字符串后,可以使用普通NSString或再次致电setAttributedTitle

答案 2 :(得分:1)

我创建了一个从UIButton扩展的自定义类 MyButton 。然后将其添加到Identity Inspector

enter image description here

在此之后,将按钮类型更改为自定义

enter image description here

然后,您可以针对不同的状态为textColor设置UIFontUIButton等属性:

enter image description here

然后我还在MyButton类中创建了两个方法,当我希望UIButton显示为突出显示时,我必须在我的代码中调用:

- (void)changeColorAsUnselection{
    [self setTitleColor:[UIColor colorFromHexString:acColorGreyDark] 
               forState:UIControlStateNormal & 
                        UIControlStateSelected & 
                        UIControlStateHighlighted];
}

- (void)changeColorAsSelection{
    [self setTitleColor:[UIColor colorFromHexString:acColorYellow] 
               forState:UIControlStateNormal & 
                        UIControlStateHighlighted & 
                        UIControlStateSelected];
}

您必须将titleColor设置为普通,突出显示并选中UIControlState,因为根据UIControlState的文档,一次可以有多个州。 如果您不创建这些方法,UIButton会显示选择或突出显示,但他们不会留在您UIColor内设置的UIInterface Builder,因为它们只是可用于选择的简短显示,而不是显示选择本身。

答案 3 :(得分:0)

就我而言,我使用的是XCode 7.x。

我遇到了类似的问题。使用NSAttributedString后

let underlineAttribute = [NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue]
        let underlineAttributedString = NSAttributedString(string: "FILTER", attributes: underlineAttribute)
        filterButton.setTitleColor(AppConfig.FOREGROUND, forState: .Normal)
        filterButton.setAttributedTitle(underlineAttributedString, forState: .Normal)

filterButton.setTitleColor(AppConfig.FOREGROUND,forState:.Normal)不受影响。

我更改了界面生成器中按钮的色调颜色(默认为浅蓝色)。现在,它现在适用于我。

答案 4 :(得分:0)

上述答案的替代方法是使用字符串属性应用文本颜色。您可以为每个控件状态设置不同的NSAttributedString,这样可以达到相同的效果 - 按钮文本将在选择/突出显示时更改颜色。

示例:

// We're assuming attributedString already exists - this is your completed attributed string so far
// We're going to copy this string into two more NS(Mutable)AttributedString variables - one for the "normal" state and one for the "highlighted" state
NSMutableAttributedString *normalAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString];
// Set the desired foreground color (in this case it's for the "normal" state) for the length of the string
[normalAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(0,attributedString.length)];

// Rinse and repeat for the highlighted state
NSMutableAttributedString *highlightedAttributedString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString];
[highlightedAttributedString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0,attributedString.length)];

// Finally, we'll set these as the attributedTitles for the relevant control states.
[myButton setAttributedTitle:normalAttributedString forState:UIControlStateNormal];
[myButton setAttributedTitle:highlightedAttributedString forState:UIControlStateSelected];
[myButton setAttributedTitle:highlightedAttributedString forState:UIControlStateHighlighted];

答案 5 :(得分:-2)

我立即注意到了这一点。只是一个简单的错误:))

更改

UIColor *btnTextColor = [UIColor colorWithRed:(147/255.f) 
                                        green:(147/255.f) 
                                         blue:(147/255.f) alpha:1.0];

UIColor *btnTextColor = [UIColor colorWithRed:(147/255.0f) 
                                        green:(147/255.0f) 
                                         blue:(147/255.0f) alpha:1.0];

它没有改变的原因可能是因为它没有识别UIColor因为你没有在分区中有一个完整的数字,因为它看到(147/255。) 而不是(147 / 255.0)

相关问题