¿Cómo cambiar el color del text del button UIAlertController en iOS9?

La pregunta es similar a la del UIActivityViewController de iOS 8 y el color del text del button UIAlertController utiliza tintColor de la window, pero en iOS 9.

Tengo un UIAlertController y el button de rechazo mantiene el color blanco, incluso he intentado configurar

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

Me he encontrado con algo similar en el pasado y el problema parece derivarse del hecho de que la vista del controller de alerta no está list para aceptar los cambios de tintColor antes de que se presente. Como alternativa, intente configurar el color de tinte DESPUÉS de presentar su controller de alerta:

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

Pude resolver esto UIAlertController :

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

Esto sobrevive a la rotation de un dispositivo mientras se muestra la alerta.

Tampoco es necesario configurar el tintColor después de presentar la alerta cuando se usa esta subclass.

Aunque no es necesario en iOS 8.4, este código también funciona en iOS 8.4.

La implementación de Objective-C debería ser algo como esto:

 @interface MyUIAlertController : UIAlertController @end @implementation MyUIAlertController -(void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; //set this to whatever color you like... self.view.tintColor = [UIColor blackColor]; } @end 
 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title text" message:@"Message text" prefernetworkingStyle: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 networkingColor] forKey:@"titleTextColor"]; [alertController addAction:ok]; [alertController addAction:cancel]; [alertController.view setTintColor:[UIColor yellowColor]]; [self presentViewController:alertController animated:YES completion:nil]; 

Existe un problema con la configuration del color de tinte en la vista después de la presentación; incluso si lo hace en el bloque de finalización de presentViewController: animated: completion :, produce un efecto de parpadeo sobre el color de los títulos de los botones. Esto es descuidado, poco profesional y completamente inaceptable.

La única forma segura de resolver este problema y hacerlo en todas partes es agregando una categoría a UIAlertController y haciendo swizzling the viewWillAppear.

El encabezado:

 // // 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 

La implementación:

 // // 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 networking-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 

Agregue un .pch (encabezado precomstackdo) a su proyecto e incluya la categoría:

 #import "UIAlertController+iOS9TintFix.h" 

Asegúrese de registrar su pch en el proyecto correctamente, e includeá los methods de categoría en cada class que utiliza el UIAlertController.

Luego, en los delegates de la aplicación método didFinishLaunchingWithOptions, importe su categoría y llame

 [UIAlertController tintFix]; 

y se propagará automáticamente a cada instancia única de UIAlertController dentro de su aplicación, ya sea iniciada por su código o por cualquier otra persona.

Esta solución funciona tanto para iOS 8.X como para iOS 9.X y carece del parpadeo del enfoque de post-presentación de cambio de tinte.

¡Apoyos locos para Brandon arriba por comenzar este viaje, desafortunadamente mi reputación no fue suficiente para comentar su publicación, o de lo contrario la hubiera dejado allí!

En Swift 3.x:

Encontré lo siguiente para trabajar de manera efectiva. Llamo a esto al inicio de la aplicación.

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

Entonces, esto cambiaría el color de tinte de todas las tags de los botones UIAlertViewController en su aplicación a nivel mundial. El único color de la label del button que no cambia son los que tienen un UIAlertActionStyle de destructivo.

Encontré una solución a esto. No es una solución elegante, sino una solución.

He swizzled viewWillAppear: en UIAlertController, luego recorrí las vistas y modifiqué el color del tinte. En mi caso tenía un set de tintColor en toda la window y, a pesar de configurar el tintColor mediante apariencia, el UIAlertController mantenía el color en la window. Comprobo si el color es igual al de la window y, si es así, aplique uno nuevo. Al aplicar ciegamente tintColor a todas las vistas, se restablecerá el tinte rojo en las acciones destructivas.

 + (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 shanetworkingApplication].keyWindow; for (UIView *v in view.subviews) { if ([v.tintColor isEqual:mainWindow.tintColor]) { v.tintColor = [UIColor greenColor]; } [self applyTintToView:v]; } } 

Sin embargo, esto no funciona en iOS 8, por lo que necesitará configurar el color de tinte de apariencia.

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

swift3

UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = MyColor usar UIView.appearance(whenContainedInInstancesOf: [UIAlertController.self]).tintColor = MyColor pero esto evita que otros elementos no relacionados con el UIAlertController de la configuration tintColor. Lo vi al intentar cambiar el color de los elementos del button de la barra de navigation.

Cambié a una extensión (basada en la respuesta de Mike Taverne arriba) y funciona muy bien.

 extension UIAlertController { override open func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() //set this to whatever color you like... self.view.tintColor = MyColor } } 
 [[UIView appearance] setTintColor:[UIColor black]]; 

esto cambiará todos los UIView tintColor así como la vista de UIAlertController

Puede cambiarlo usando: Swift 3.x

  strongController.view.tintColor = UIColor.green 

En Swift 2.2 puedes usar el siguiente código

  // LogOut or Cancel let logOutActionSheet: UIAlertController = UIAlertController(title: "Hello Mohsin!", message: "Are you sure you want to logout?", prefernetworkingStyle: .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.networkingColor(), forKey: "titleTextColor") logOutActionSheet.addAction(logOutActionButton) 

Tienes 3 styles para los botones de acción:

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

Quería hacer que el button Eliminar apareciera en rojo, así que usé el estilo .destructivo:

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