如何在iOS9中更改UIAlertControllerbutton的文本颜色?

问题类似于iOS 8 UIActivityViewController和UIAlertControllerbutton文本颜色使用窗口的tintColor,但在iOS 9。

我有一个UIAlertController和解雇button保持白色,即使我试图设置

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blackColor]]; UIAlertController *strongController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:preferredStyle]; strongController.view.tintColor = [UIColor black]; 

我遇到过类似的问题,这个问题似乎源于这样一个事实,即警报控制器的视图在呈现之前还没有准备好接受tintColor更改。 或者,尝试设置色调颜色后,您提出您的警报控制器:

 [self presentViewController:strongController animated:YES completion:nil]; strongController.view.tintColor = [UIColor black]; 

我能够通过UIAlertController来解决这个UIAlertController

 class MyUIAlertController: UIAlertController { override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() //set this to whatever color you like... self.view.tintColor = UIColor.blackColor() } } 

当警报显示时,这在设备旋转中仍然存在。

在使用此子类时,您也不需要在显示警报之后设置tintColor。

虽然在iOS 8.4上没有必要,但是这个代码也可以在iOS 8.4上运行。

Objective-C的实现应该是这样的:

 @interface MyUIAlertController : UIAlertController @end @implementation MyUIAlertController -(void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; //set this to whatever color you like... self.view.tintColor = [UIColor blackColor]; } @end 

Objective-C的

 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title text" message:@"Message text" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* ok = [UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { //code here… }]; UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Later" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { //code here…. }]; [ok setValue:[UIColor greenColor] forKey:@"titleTextColor"]; [cancel setValue:[UIColor redColor] forKey:@"titleTextColor"]; [alertController addAction:ok]; [alertController addAction:cancel]; [alertController.view setTintColor:[UIColor yellowColor]]; [self presentViewController:alertController animated:YES completion:nil]; 

Swift 3

 let alertController = UIAlertController(title: "Title text", message: "Message text", preferredStyle: .alert) let ok = UIAlertAction(title: "Yes" , style: .default) { (_ action) in //code here… } let cancel = UIAlertAction(title: "Later" , style: .default) { (_ action) in //code here… } ok.setValue(UIColor.green, forKey: "titleTextColor") cancel.setValue(UIColor.red, forKey: "titleTextColor") alertController.addAction(ok) alertController.addAction(cancel) alertController.view.tintColor = .yellow self.present(alertController, animated: true, completion: nil) 

呈现后在视图上设置色彩的颜色有问题; 即使在presentViewController:animated:completion:的完成块中执行此操作,也会对button标题的颜色产生闪烁效果。 这是草率的,不专业的,完全不能接受的。

解决这个问题并在任何地方解决这个问题的一个肯定的方法是通过向UIAlertController添加一个类别并调整viewWillAppear。

标题:

 // // UIAlertController+iOS9TintFix.h // // Created by Flor, Daniel J on 11/2/15. // #import <UIKit/UIKit.h> @interface UIAlertController (iOS9TintFix) + (void)tintFix; - (void)swizzledViewWillAppear:(BOOL)animated; @end 

执行:

 // // UIAlertController+iOS9TintFix.m // // Created by Flor, Daniel J on 11/2/15. // #import "UIAlertController+iOS9TintFix.h" #import <objc/runtime.h> @implementation UIAlertController (iOS9TintFix) + (void)tintFix { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method method = class_getInstanceMethod(self, @selector(viewWillAppear:)); Method swizzle = class_getInstanceMethod(self, @selector(swizzledViewWillAppear:)); method_exchangeImplementations(method, swizzle);}); } - (void)swizzledViewWillAppear:(BOOL)animated { [self swizzledViewWillAppear:animated]; for (UIView *view in self.view.subviews) { if (view.tintColor == self.view.tintColor) { //only do those that match the main view, so we don't strip the red-tint from destructive buttons. self.view.tintColor = [UIColor colorWithRed:0.0 green:122.0/255.0 blue:1.0 alpha:1.0]; [view setNeedsDisplay]; } } } @end 

将.pch(预编译头文件)添加到您的项目中,并包含以下类别:

 #import "UIAlertController+iOS9TintFix.h" 

确保在项目中正确注册你的pch,并在每个使用UIAlertController的类中包含类别方法。

然后,在您的应用程序代表didFinishLaunchingWithOptions方法中,导入您的类别并调用

 [UIAlertController tintFix]; 

它会自动传播到您的应用程序中的每个UIAlertController实例,无论是由您的代码或其他人启动。

这个解决scheme适用于iOS 8.X和iOS 9.X,并且没有tint change post-presentation方法的闪烁。

为了开始这个旅程,疯狂的道具让布兰登在上面,不幸的是,我的名声还不足以评论他的职位,否则我会把它留在那里!

在Swift 3.x中:

我发现以下工作有效。 我在应用程序启动时调用这个。

 UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = UIColor.black 

所以这将改变全球所有UIAlertViewControllerbutton标签的色调。 唯一不变的button标签颜色是具有破坏性的UIAlertActionStyle。

swift3

试图使用UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = MyColor但这从tintColorconfiguration可以防止与UIAlertController无关的其他项目。 我在试图改变导航栏button项目的颜色时看到了它。

我切换到扩展(基于迈克Taverne的回应上面),它的效果很好。

 extension UIAlertController { override open func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() //set this to whatever color you like... self.view.tintColor = MyColor } } 

我find了一个解决scheme。 不是一个优雅的解决scheme,而是一个解

我swizzled viewWillAppear:在UIAlertController,然后遍历视图,并修改色调的颜色。 在我的情况下,我在整个窗口上设置了tintColor,尽pipe通过外观设置了tintColor,UIAlertController保持了窗口上的颜色。 我检查颜色是否等于窗口的颜色,如果是这样,应用一个新的。 盲目地将tintColor应用于所有视图将导致重置破坏性动作的红色色彩。

 + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method swizzleMethod = class_getInstanceMethod(self, @selector(viewWillAppear:)); Method method = class_getInstanceMethod(self, @selector(alertSwizzle_viewWillAppear:)); method_exchangeImplementations(method, swizzleMethod); }); } - (void)alertSwizzle_viewWillAppear:(BOOL)animated { [self alertSwizzle_viewWillAppear:animated]; [self applyTintToView:self.view]; } - (void)applyTintToView:(UIView *)view { UIWindow *mainWindow = [UIApplication sharedApplication].keyWindow; for (UIView *v in view.subviews) { if ([v.tintColor isEqual:mainWindow.tintColor]) { v.tintColor = [UIColor greenColor]; } [self applyTintToView:v]; } } 

但是,这不适用于iOS 8,所以你仍然需要设置外观色彩的颜色。

 [[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor greenColor]]; 
 [[UIView appearance] setTintColor:[UIColor black]]; 

这将改变所有的UIView tintColor以及UIAlertController的视图

在Swift 2.2中,你可以使用下面的代码

  // LogOut or Cancel let logOutActionSheet: UIAlertController = UIAlertController(title: "Hello Mohsin!", message: "Are you sure you want to logout?", preferredStyle: .Alert) self.presentViewController(logOutActionSheet, animated: true, completion: nil) let cancelActionButton: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in print("Cancel Tapped") } logOutActionSheet.addAction(cancelActionButton) let logOutActionButton: UIAlertAction = UIAlertAction(title: "Clear All", style: .Default) { action -> Void in //Clear All Method print("Logout Tapped") } logOutActionButton.setValue(UIColor.redColor(), forKey: "titleTextColor") logOutActionSheet.addAction(logOutActionButton) 

您可以使用Swift 3.x进行更改

  strongController.view.tintColor = UIColor.green 

你有3种风格的动作button:

 let style : UIAlertActionStyle = .default // default, cancel (bold) or destructive (red) let alertCtrl = UIAlertController(....) alertCtrl.addAction( UIAlertAction(title: "click me", style: style, handler: { _ in doWhatever() })) 

我想让删除button显示为红色,所以我使用了破坏性的风格:

  alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler:{(UIAlertAction) in