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.
Thanks!
UPDATED
Per @Timothy Moose's answer, below is the updated code.
- (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]];
}
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.
Also it is very important not to have the button on System style, just put it on custom... This is for similar questions, not for this particular question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With