可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The question is similar to iOS 8 UIActivityViewController and UIAlertController button text color uses window's tintColor but in iOS 9.
I have a UIAlertController and the dismiss button keeps white colour even I have tried to set
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor blackColor]]; UIAlertController *strongController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:preferredStyle]; strongController.view.tintColor = [UIColor black];
回答1:
I've run into something similar in the past and the issue seems to stem from the fact that the alert controller's view isn't ready to accept tintColor
changes before it's presented. Alternatively, try setting the tint color AFTER you present your alert controller:
[self presentViewController:strongController animated:YES completion:nil]; strongController.view.tintColor = [UIColor black];
回答2:
I was able to solve this by subclassing UIAlertController
:
class MyUIAlertController: UIAlertController { override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() //set this to whatever color you like... self.view.tintColor = UIColor.blackColor() } }
This survives a device rotation while the alert is showing.
You also don't need to set the tintColor after presenting the alert when using this subclass.
Though it isn't necessary on iOS 8.4, this code does work on iOS 8.4 as well.
Objective-C implementation should be something like this:
@interface MyUIAlertController : UIAlertController @end @implementation MyUIAlertController -(void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; //set this to whatever color you like... self.view.tintColor = [UIColor blackColor]; } @end
回答3:
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)
回答4:
In Swift 3.x:
I found the following to work effectively. I call this at app launch .
UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = UIColor.black
So this would change the tint color of all UIAlertViewController button labels in your app globally. The only button label color it doesn't change are those which have a UIAlertActionStyle of destructive.
回答5:
There is a problem with setting the tint color on the view after presenting; even if you do it in the completion block of presentViewController:animated:completion:, it causes a flicker effect on the color of the button titles. This is sloppy, unprofessional and completely unacceptable.
The one sure-fire way to solve this problem and to do it everywhere, is via adding a category to UIAlertController and swizzling the viewWillAppear.
The header:
// // UIAlertController+iOS9TintFix.h // // Created by Flor, Daniel J on 11/2/15. // #import @interface UIAlertController (iOS9TintFix) + (void)tintFix; - (void)swizzledViewWillAppear:(BOOL)animated; @end
The implementation:
// // UIAlertController+iOS9TintFix.m // // Created by Flor, Daniel J on 11/2/15. // #import "UIAlertController+iOS9TintFix.h" #import @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
Add a .pch (precompiled header) to your project and include the category:
#import "UIAlertController+iOS9TintFix.h"
Make sure you register your pch in the project properly, and it will include the category methods in every class that uses the UIAlertController.
Then, in your app delegates didFinishLaunchingWithOptions method, import your category and call
[UIAlertController tintFix];
and it will automatically propagate to every single instance of UIAlertController within your app, whether launched by your code or anyone else's.
This solution works for both iOS 8.X and iOS 9.X and lacks the flicker of the tint change post-presentation approach.
Mad props to Brandon above for starting this journey, unfortunately my reputation was not sufficient enough to comment on his post, or else I would have left it there!
回答6:
[[UIView appearance] setTintColor:[UIColor black]];
this will change all the UIView tintColor
as well as UIAlertController
's view
回答7:
swift3
Tried to use UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = MyColor
but this prevents other items unrelated to the UIAlertController
from tintColor configuration. I saw it while trying to change the color of navigation bar button items.
I switched to an extension (based on Mike Taverne's response above) and it works great.
extension UIAlertController { override open func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() //set this to whatever color you like... self.view.tintColor = MyColor } }
回答8:
I found a solution to this. Not an elegant solution, but a solution.
I swizzled viewWillAppear: on UIAlertController, then looped through the views and modified the tint color. In my case I had a tintColor set on the entire window and despite setting the tintColor via appearance the UIAlertController maintained the color on the window. I check if the color is equal to that of the window and if so apply a new one. Blindly applying the tintColor to all views will result in the red tint on destructive actions to be reset.
+ (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]; } }
However this doesn't work on iOS 8, so you'll still need to set the apperance tint color.
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor greenColor]];
回答9:
In Swift 2.2 you can use following code
// 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)
回答10:
You can change it using: Swift 3.x
strongController.view.tintColor = UIColor.green
回答11:
You have 3 styles for the action buttons:
let style : UIAlertActionStyle = .default // default, cancel (bold) or destructive (red) let alertCtrl = UIAlertController(....) alertCtrl.addAction( UIAlertAction(title: "click me", style: style, handler: { _ in doWhatever() }))
回答12:
I wanted to make the delete button to appear red, so I used .destructive style:
alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler:{(UIAlertAction) in