Change Text Color of Items in UIActionSheet - iOS 8
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 in iOS8
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
using iOS8
??
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 always false
for all items of actionSheet.subviews
. So what I think is that the view heirarchy of
UIActionSheet
has been changed.
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)
}
}
}
}