iosobjective-cuibutton

Title color of UIButton won't change on highlighted/selected but background color will


This has been a very odd process.

I have an IBOutletCollection of UIButtons. I loop through the collection and create them like this (the displayHourButtons is called from 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++;
    }
}

When one of the buttons is clicked, per the action showHour: is called:

- (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]];
}

I tried all sorts of crazy things to get the UIImage to be in a selected state, but nothing worked. This enumerateObjects deal is the only thing that has worked. That's why I say this has been an odd process. I guess buttons don't stay active indefinitely?

Anyways, MY QUESTION: Is there a certain reason why the title color isn't changing? Just the background? I suspect it has something to do with the background not being set initially, but I couldn't explain why.


Solution

  • setTitleColor doesn't have any effect when the title is an attributed string. Either use a plain NSString or call setAttributedTitle again after applying the desired color to the attributed string.