Change text color in UIActionSheet buttons
Asked Answered
N

12

38

In my project, I am using UIActionSheet for displaying for some sorting type. I want to change the color of the text displayed in the action sheet buttons. How can we change the text color?

Nebuchadnezzar answered 23/4, 2013 at 7:44 Comment(0)
R
79

iOS 8: UIActionSheet is deprecated. UIAlertController respects -[UIView tintColor], so this works:

alertController.view.tintColor = [UIColor redColor];

Better yet, set the whole window's tint color in your application delegate:

self.window.tintColor = [UIColor redColor];

iOS 7: In your action sheet delegate, implement -willPresentActionSheet: as follows:

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{
    for (UIView *subview in actionSheet.subviews) {
        if ([subview isKindOfClass:[UIButton class]]) {
            UIButton *button = (UIButton *)subview;
            [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        }
    }
}
Ruth answered 3/10, 2013 at 20:24 Comment(11)
This works only default state. If you tap the button, it keep blue color on the titleLabel.Chemotropism
Thanks. Try [button setTitleColor:fooColor forState:UIControlStateNormal] instead.Ruth
This just doesn't work at all on the iPhone simulator.Household
Reuben - Not sure what you're doing wrong but it works fine in Simulator.Celindaceline
People, stop iterating through Apple's private controls subviews. This is bad, will crash one day and will make other developers laugh at you.Downstairs
@Downstairs it's only private if it's not public. But it doesn't make it wrong, especially if Apple approves them. It's a shame Apple has to restrict access to simple fundamental features like the colors of a string just so we have to go and create our own from scratch. Have you ever tried to change the title color of the cancel button in a UISearchBar? I guess Apple thinks everyone sees only blueSextant
This is a guidelines violation, while setting your custom color to the destructive buttons (if one is presented in your sheet), which must be red.Widget
You are using something you assume Apple won't change, which is not the case in iOS 8, the code is not safeChirrup
Guys, this isn't using a private API; -[UIView subviews] is very much public. But changing text color this way is of course not what Apple intended, so you could say it is private "in spirit". If your designer or product owner asks for this to be done, here is a way. If you don't think it should be done, don't do it. End of story.Ruth
Yes it's not using private API but you are assuming the subviews inside the action sheet will remain UIButtons which is not valid, they might change by Apple cause they are not documented and not provided through public APIChirrup
@Downstairs iterating using strong condition dont crash anything. I've olds app with ios 6 sdk actually running in ios9 devices..what do you understand is what do you doing..Fr
T
20

In iOS 8, none of this works anymore. UIActionSheet text seems to get its color from window.tintColor.

Tarah answered 21/8, 2014 at 22:28 Comment(3)
Sorry for the late reply. My workaround was to stop changing window.tintColor or self.view.tintColor to white. Instead, I'm now explicitly setting any elements which need a white tintColor, rather than relying upon parent view tintColors.Tarah
Nice post! I was wondering all the time why my UIAlertViews and UIAlertControllerappear in whiteColor.Fluviatile
In iOS8, UIActionSheet is deprecated. You can use UIAlertController and set tintColor on the alert controller view.Quiteri
H
17

This works for me in iOS8

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor redColor]];
Hondo answered 12/12, 2014 at 6:52 Comment(1)
This will change the color of all the buttons, including the cancel button. Is there a way to change the color to red, but not for the cancel button?Monogenetic
B
12

If ever you want to go through the UIActionSheet's subviews, you should not directly set the text color of the UILabel but use the UIButton setTitleColor:forState method instead. Otherwise, the initial color will be set back upon events like UIControlEventTouchDragOutside for example.

Here is the proper way to do it, reusing the jrc's code:

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{
    for (UIView *subview in actionSheet.subviews) {
        if ([subview isKindOfClass:[UIButton class]]) {
            UIButton *button = (UIButton *)subview;
            [button setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        }
    }
}
Byran answered 31/10, 2013 at 13:11 Comment(0)
D
8

To change particular buttons colour in alert action use this

let cancelAction = UIAlertAction(title: "Success", style: .cancel, handler: nil)
cancelAction.setValue(UIColor.green, forKey: "titleTextColor")

Depersonalization answered 10/10, 2019 at 6:30 Comment(1)
the only thing that worked, not sure what others are smoking. thanks!Teeth
P
7

May be a late answer but I figure it could help someone.

iOS 8: You could simply initialize your UIAlertAction with the style: UIAlertActionStyleDestructive like so:

UIAlertAction *delete = [UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){

   // your code in here   

}];

This will make the button's text red by default.

enter image description here

Putandtake answered 2/2, 2017 at 17:10 Comment(0)
S
3

Soulution for Swift 3. Changes all colors.

UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = .yellow
Scheme answered 27/9, 2017 at 14:16 Comment(2)
this will change all UIAlertController's colour which is used in your app.Stiegler
but +1 from my side.Stiegler
C
2

@jrc solution works, but titleLabel color changes when you tap the button. Try this to keep the same color at all states.

- (void)willPresentActionSheet:(UIActionSheet *)actionSheet
{     
 UIColor *customTitleColor = [UIColor greenColor];
      for (UIView *subview in actionSheet.subviews) {
        if ([subview isKindOfClass:[UIButton class]]) {
          UIButton *button = (UIButton *)subview;

          [button setTitleColor:customTitleColor forState:UIControlStateHighlighted];
          [button setTitleColor:customTitleColor forState:UIControlStateNormal];
          [button setTitleColor:customTitleColor forState:UIControlStateSelected];
        }
      }
}
Chemotropism answered 1/11, 2013 at 18:21 Comment(0)
R
1

EDIT

Here is a similar question: How to customize Buttons in UIActionSheet?

Try to use the appearance protocol [NOT WORKING]

 UIButton *btn = [UIButton appearanceWhenContainedIn:[UIActionSheet class], nil];
 [btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
Roice answered 23/4, 2013 at 7:49 Comment(0)
B
1

use this for ios 8 and above

SEL selector = NSSelectorFromString(@"_alertController");
if ([actionSheet respondsToSelector:selector])
{
    UIAlertController *alertController = [actionSheet valueForKey:@"_alertController"];
    if ([alertController isKindOfClass:[UIAlertController class]])
    {
        alertController.view.tintColor = [UIColor blueColor];
    }
}
else
{
    // use other methods for iOS 7 or older.
}
Brachyuran answered 22/9, 2015 at 4:28 Comment(0)
P
0

UIAppearance can handle this:

[[UIButton appearanceWhenContainedIn:[UIActionSheet class], nil] setTitleColor:[UIColor cyanColor] forState:UIControlStateNormal];

Much easier than going through the subviews, but I haven't tested this solution on iOS 6 or earlier.

Peag answered 22/6, 2014 at 12:8 Comment(0)
A
0

In Swift smth like this:

let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
actionSheet.view.tintColor = UIColor.primary
Adoration answered 6/5, 2022 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.