Change Text Color of Items in UIActionSheet - iOS 8
Solution 1
There's an easy way if you still want to use UIActionSheet
instead of UIAlertController
in order to support older iOS versions.
UIActionSheet
actually uses UIAlertController
in iOS 8, and it has a private property _alertController
.
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.
}
For Swift Below code should works
let alertAction = UIAlertAction(title: "XXX", style: .default) { (action) in
}
alertAction.setValue(UIColor.red, forKey: "titleTextColor")
Solution 2
To change the button title color you need to use UIAlertController
and set the tintColor
of the main view
.
Example of setting the button title colors to black:
UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:@"How would you like to proceed?" message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *finish = [UIAlertAction actionWithTitle:@"Finish" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
[self performSelector:@selector(finish:) withObject:nil];
}];
UIAlertAction *playAgain = [UIAlertAction actionWithTitle:@"Play Again" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
{
[self performSelector:@selector(playAgain:) withObject:nil];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action)
{
[actionSheetController dismissViewControllerAnimated:YES completion:nil];
}];
[actionSheetController addAction:finish];
[actionSheetController addAction:playAgain];
[actionSheetController addAction:cancel];
//******** THIS IS THE IMPORTANT PART!!! ***********
actionSheetController.view.tintColor = [UIColor blackColor];
[self presentViewController:actionSheetController animated:YES completion:nil];
Solution 3
Ok, I ran into the same problem but I think I have found a solution:
The appropriate way should be like this and I guess it works in iOS7:
[[UIButton appearanceWhenContainedIn:[UIActionSheet class], nil] setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
But it will not work in iOS8 due to the fact that the ActionSheets "buttons" is now based on a UICollectionView. So after some digging around I got this to work instead:
[[UICollectionView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blueColor]];
Solution 4
I'm using it.
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blueColor]];
Add one line (AppDelegate) and works for all UIAlertController.
Solution 5
I have same task and I've made this hack today, dirty, but it works
class CustomAlertViewController: UIAlertController {
internal var cancelText: String?
private var font: UIFont? = UIFont(name: "MuseoSansCyrl-500", size: 12)
override func viewDidLoad() {
super.viewDidLoad()
self.view.tintColor = UIColor.blackColor()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.findLabel(self.view) //if you need ios 9 only, this can be made in viewWillAppear
}
func findLabel(scanView: UIView!) {
if (scanView.subviews.count > 0) {
for subview in scanView.subviews {
if let label: UILabel = subview as? UILabel {
if (self.cancelText != nil && label.text == self.cancelText!) {
dispatch_async(dispatch_get_main_queue(),{
label.textColor = UIColor.redColor() //for ios 8.x
label.tintColor = UIColor.redColor() //for ios 9.x
})
}
if (self.font != nil) {
label.font = self.font
}
}
self.findLabel(subview)
}
}
}
}
![Salman Zaidi](https://i.stack.imgur.com/9Criy.jpg?s=256&g=1)
Salman Zaidi
Updated on July 09, 2022Comments
-
Salman Zaidi almost 2 years
I had been using following code to change text color of items which I add in
UIActionSheet
.:- (void)willPresentActionSheet:(UIActionSheet *)actionSheet { for (UIView *subview in actionSheet.subviews) { if ([subview isKindOfClass:[UIButton class]]) { UIButton *button = (UIButton *)subview; [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; } } }
It works fine in
iOS7
, but iniOS8
the above code doesn't change the text color of items.Now my question is how to change the text color of items which I add in
UIActionSheet
usingiOS8
??
Additional Info:
I added breakpoint to see whether following lines from the above code get executed or not:UIButton *button = (UIButton *)subview; [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
These lines do not get executed. So,
if([subview isKindOfClass:[UIButton class]])
is alwaysfalse
for all items ofactionSheet.subviews
. So what I think is that the view heirarchy ofUIActionSheet
has been changed. -
Jorge almost 10 yearsThis is a great answer. Although, I'm still looking for a way to set each button tint as well as the backgroundColor of the
UIAlertController
. Any thoughts? -
DiscDev almost 10 years@Jorge I remember reading somewhere that Apple doesn't want you to customize action sheet / alert colors. I believe that if you want to do more customizations than what I mentioned you'd need to make your own alert class, or borrow one of the many readily available open source options from github.
-
Jorge almost 10 yearsYes, that's what I thought. Actually, I do use
UIView
with buttons for this purpose sometimes, but it would be a lot easier to just customizeUIAlertController
. Thanks a lot. @DiscDev -
Mundi almost 10 yearsThis is not working with style
.Alert
. Most likely Apple does not foresee the modification of alerts. -
Teffi almost 10 yearsCan we at least change the font and title color? Apple should atleast allowed us to do simple customization rather than using uiview that would function like an alertview or actionsheet.
-
Tim almost 10 yearsYes, part of the purpose of GUI (graphical) is to make it clear and obvious sometimes by color, such as when one is about to Delete something, the color red is used to indicate, you are about to do something with potential consequences. Some of apples choices since Steve Job's passing do not seem wise.
-
DiscDev almost 10 years@Tim the iOS SDK has never allowed you to customize action sheets or alerts colors from version 1. Doesn't have anything to do with the late Mr. Jobs. They want a consistent experience. If you want something more flexible, you'll have to make it yourself.
-
Whoami over 9 yearsDiscDev, thanks, is it possible to change the individual UIAlertAction button different color?
-
DiscDev over 9 years@Whoami doubtful. Apple doesn't want you to customize alerts/actionsheets. They suggest you make your own if you want a custom look and feel. There are lots of projects on github for this, go have a look there.
-
huong over 9 yearsAm I the only sees that this changes color for all buttons except for Cancel button?
-
DiscDev over 9 yearsThis will definitely have unintended side effects and is not advised. Changing the tint color for all UICollectionViews inside UIAlertController is fragile and relies on the view hierarchy Apple has chosen for the current version of iOS. As you can see from this answer, they changed the view hierarchy from iOS 7-> iOS 8, what's to keep them from doing it again in iOS 9? This will surely require updating in the future and is not advised.
-
André Fratelli over 9 yearsUsing private properties will probably get the app rejected
-
Saren Inden over 9 yearsTo do this correct you should use UIActionSheet and UIAlertView on iOS7 and below and UIAlertController on iOS8 and above. For my projects I wrote a 'custom' AlertController that automatically picks the right method based on the OS version. To bad I cannot share but I would definitely recommend doing this also because there are some bugs that might occur on iOS8 when using UIActionSheet
-
matzino over 9 yearsSetting the tintColor works well, but the gap between Default- and Cancel-Style-Items is than missing :(
-
Benjohn over 9 yearsBest solution imo. I added a few tweaks for backwards compatibility and to get the default tint colour, which isn't
UIColor.blueColor
. -
Benjohn over 8 yearsThis doesn't work for iPads on iOS 9, for some reason. Poo. :-(
-
whyoz over 8 years[self.window setTintColor:[UIColor whateverColor]] is the only thing I've found that works in iOS 8 and 9
-
Benjohn over 8 years@whyoz I'll look at that – I've already set this to something else for some reason, but perhaps I can achieve that elsewhere…
-
mnl over 8 years@friedegg-bacon-sandwich i'm getting everything in tint color except the cancel button as well. looks extremely stupid. do you know how to set the cancel button to tint color as well?
-
qqilihq over 8 yearsWhile this does not answer OP's question, it just solved my specific issue. Thanks!
-
BFeher over 8 years@friedegg-bacon-sandwich Did anybody ever solve the stubborn cancel button issue?
-
Syed Ali Salman about 8 yearsWill this be rejected by apple? If I use this?
-
AbdulMomen عبدالمؤمن about 8 yearsthis answer is the best.
-
Pauls almost 8 yearsI had to set actionSheetController.view.tintColor = [UIColor blackColor]; again in the completion block to have not flicker the color after tapping on the buttons!
-
Tung Vu Duc almost 6 yearsGreat, but how do you know that pro ?
-
infiniteLoop over 2 yearsThis has been answered above already. Also it will be rejected as already pointed out.