The color of the UIButton header will not change to the selected / selected, but the background color will be

It was a very strange process.

I have an IBOutletCollection UIButtons. I scroll through the collection and create it like this ( 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 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 pressed, the showHour: action 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 kinds of crazy things to make UIImage be in the selected state, but nothing worked. This transaction enumerateObjects is the only thing that worked. That is why I say that it was a strange process. I think the buttons do not remain active indefinitely?

In any case, MY QUESTION : Is there a definite reason why the color of the title does not change? Just the background? I suspect that this has something to do with the fact that the background was not set initially, but I could not explain why.

Thanks!

UPDATED

In response to @Timothy Moose, 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]]; } 
+6
source share
6 answers

setTitleColor has no effect if the title is an attribute string. Either use regular NSString , or call setAttributedTitle again after applying the desired color to the assigned string.

+16
source

It is also very important not to have a button in the System style, just put it on your custom ... This concerns similar issues, and not for this specific issue.

+14
source

I created a custom MyButton class extended from UIButton . Then add this inside the Identity Inspector :

enter image description here

After that, change the button type to Custom :

enter image description here

Then you can set attributes like textColor and UIFont for your UIButton for different states:

enter image description here

Then I also created two methods inside the MyButton class that I need to call inside my code when I want the UIButton appear as highlighted:

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

You must set the titleColor for the normal, selected and selected UIControlState , because according to the documentation, UIControlState can have more than one state at a time. If you do not create these methods, UIButton display the selection or selection, but they will not remain in the UIColor that you set inside the UIInterface Builder , because they are simply available to briefly display the selection, and not to display the selection itself.

0
source

In my case, I am using Xcode 7.x.

I ran into a similar problem. After using 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) 

filter Button.setTitleColor (AppConfig.FOREGROUND, forState: .Normal) will not be executed.

I am changing the hue of the button in the interface builder (which is blue by default). Now it works for me now.

0
source

An alternative to the answers above is to apply text color using string attributes. You can set a different NSAttributedString for each control state, so this works to achieve the same effect - the button text will change color to selection / selection.

Example:

 // 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 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]; 
0
source

I immediately noticed this. Probably a simple mistake :)

Change

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

to

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

The reason why it did not change is probably due to the fact that it did not recognize UIColor , since you did not have the full number in the section, because it saw (147/255.) Instead of (147 / 255.0)

-2
source

Source: https://habr.com/ru/post/955329/


All Articles