UIAlertController fuente personalizada, tamaño, color

Estoy usando el nuevo UIAlertController para mostrar alertas. Tengo este código:

// nil titles break alert interface on iOS 8.0, so we'll be using empty strings UIAlertController *alert = [UIAlertController alertControllerWithTitle: title == nil ? @"": title message: message prefernetworkingStyle: UIAlertControllerStyleAlert]; UIAlertAction *defaultAction = [UIAlertAction actionWithTitle: cancelButtonTitle style: UIAlertActionStyleCancel handler: nil]; [alert addAction: defaultAction]; UIViewController *rootViewController = [UIApplication shanetworkingApplication].keyWindow.rootViewController; [rootViewController presentViewController:alert animated:YES completion:nil]; 

Ahora quiero cambiar la fuente, el color, el tamaño y el tipo de título y post. ¿Cuál es la mejor manera de hacer esto?

Editar: Debería insert el código completo. Creé una categoría para UIView que podía mostrar la alerta derecha para la versión de iOS.

 @implementation UIView (AlertCompatibility) +( void )showSimpleAlertWithTitle:( NSString * )title message:( NSString * )message cancelButtonTitle:( NSString * )cancelButtonTitle { float iOSVersion = [[UIDevice currentDevice].systemVersion floatValue]; if (iOSVersion < 8.0f) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle: title message: message delegate: nil cancelButtonTitle: cancelButtonTitle otherButtonTitles: nil]; [alert show]; } else { // nil titles break alert interface on iOS 8.0, so we'll be using empty strings UIAlertController *alert = [UIAlertController alertControllerWithTitle: title == nil ? @"": title message: message prefernetworkingStyle: UIAlertControllerStyleAlert]; UIAlertAction *defaultAction = [UIAlertAction actionWithTitle: cancelButtonTitle style: UIAlertActionStyleCancel handler: nil]; [alert addAction: defaultAction]; UIViewController *rootViewController = [UIApplication shanetworkingApplication].keyWindow.rootViewController; [rootViewController presentViewController:alert animated:YES completion:nil]; } } 

No estoy seguro de si esto está en contra de las API / properties privadas, pero el uso de KVC funciona para mí en ios8

 UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"Dont care what goes here, since we're about to change below" message:@"" prefernetworkingStyle:UIAlertControllerStyleActionSheet]; NSMutableAttributedString *hogan = [[NSMutableAttributedString alloc] initWithString:@"Presenting the great... Hulk Hogan!"]; [hogan addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:50.0] range:NSMakeRange(24, 11)]; [alertVC setValue:hogan forKey:@"attributedTitle"]; UIAlertAction *button = [UIAlertAction actionWithTitle:@"Label text" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){ //add code to make something happen once tapped }]; UIImage *accessoryImage = [UIImage imageNamed:@"someImage"]; [button setValue:accessoryImage forKey:@"image"]; 

Para el logging, también es posible cambiar la fuente de la acción de alerta, utilizando esas API privadas. Una vez más, es posible que la aplicación sea rechazada, aún no he intentado enviar dicho código.

 let alert = UIAlertController(title: nil, message: nil, prefernetworkingStyle: .ActionSheet) let action = UIAlertAction(title: "Some title", style: .Default, handler: nil) let attributedText = NSMutableAttributedString(string: "Some title") let range = NSRange(location: 0, length: attributedText.length) attributedText.addAttribute(NSKernAttributeName, value: 1.5, range: range) attributedText.addAttribute(NSFontAttributeName, value: UIFont(name: "ProximaNova-Semibold", size: 20.0)!, range: range) alert.addAction(action) presentViewController(alert, animated: true, completion: nil) // this has to be set after presenting the alert, otherwise the internal property __representer is nil guard let label = action.valueForKey("__representer")?.valueForKey("label") as? UILabel else { return } label.attributedText = attributedText 

Puede cambiar el color del button aplicando un color de tinte a un UIAlertController.

En iOS 9, si el color de tinte de window se configuró en un color personalizado, debe aplicar el color de tinte justo después de presentar la alerta. De lo contrario, el color de tinte se restablecerá a su color de tinte de window personalizado.

 // In your AppDelegate for example: window?.tintColor = UIColor.networkingColor() // Elsewhere in the App: let alertVC = UIAlertController(title: "Title", message: "message", prefernetworkingStyle: .Alert) alertVC.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)) alertVC.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil)) // Works on iOS 8, but not on iOS 9 // On iOS 9 the button color will be networking alertVC.view.tintColor = UIColor.greenColor() self.presentViewController(alert, animated: true, completion: nil) // Necessary to apply tint on iOS 9 alertVC.view.tintColor = UIColor.greenColor() 

Puede cambiar el color del text del button usando este código:

 alertC.view.tintColor = your color; 

Quizás esto te ayude.

Una traducción rápida de la respuesta @ dupuis2387. Se UIAlertController la syntax para establecer el color y la fuente del título del UIAlertController través de KVC utilizando la tecla de título attributedTitle .

 let message = "Some message goes here." let alertController = UIAlertController( title: "", // This gets overridden below. message: message, prefernetworkingStyle: .Alert ) let okAction = UIAlertAction(title: "OK", style: .Cancel) { _ -> Void in } alertController.addAction(okAction) let fontAwesomeHeart = "\u{f004}" let fontAwesomeFont = UIFont(name: "FontAwesome", size: 17)! let customTitle:NSString = "I \(fontAwesomeHeart) Swift" // Use NSString, which lets you call rangeOfString() let systemBoldAttributes:[String : AnyObject] = [ // setting the attributed title wipes out the default bold font, // so we need to reconstruct it. NSFontAttributeName : UIFont.boldSystemFontOfSize(17) ] let attributedString = NSMutableAttributedString(string: customTitle as String, attributes:systemBoldAttributes) let fontAwesomeAttributes = [ NSFontAttributeName: fontAwesomeFont, NSForegroundColorAttributeName : UIColor.networkingColor() ] let matchRange = customTitle.rangeOfString(fontAwesomeHeart) attributedString.addAttributes(fontAwesomeAttributes, range: matchRange) alertController.setValue(attributedString, forKey: "attributedTitle") self.presentViewController(alertController, animated: true, completion: nil) 

introduzca la descripción de la imagen aquí

Use el protocolo UIAppearance . Haz más hacks con appearanceFont para cambiar la fuente de UIAlertAction .

Crear una categoría para UILabel

UILabel + FontAppearance.h

 @interface UILabel (FontAppearance) @property (nonatomic, copy) UIFont * appearanceFont UI_APPEARANCE_SELECTOR; @end 

UILabel + FontAppearance.m

 @implementation UILabel (FontAppearance) - (void)setAppearanceFont:(UIFont *)font { if (self.tag == 1001) { return; } BOOL isBold = (self.font.fontDescriptor.symbolicTraits & UIFontDescriptorTraitBold); const CGFloat* colors = CGColorGetComponents(self.textColor.CGColor); if (self.font.pointSize == 14) { // set font for UIAlertController title self.font = [UIFont systemFontOfSize:11]; } else if (self.font.pointSize == 13) { // set font for UIAlertController message self.font = [UIFont systemFontOfSize:11]; } else if (isBold) { // set font for UIAlertAction with UIAlertActionStyleCancel self.font = [UIFont systemFontOfSize:12]; } else if ((*colors) == 1) { // set font for UIAlertAction with UIAlertActionStyleDestructive self.font = [UIFont systemFontOfSize:13]; } else { // set font for UIAlertAction with UIAlertActionStyleDefault self.font = [UIFont systemFontOfSize:14]; } self.tag = 1001; } - (UIFont *)appearanceFont { return self.font; } @end 

Uso:

añadir

[[UILabel appearanceWhenContainedIn:UIAlertController.class, nil] setAppearanceFont:nil];

en AppDelegate.m para que funcione para todo UIAlertController .

En Xcode 8 Swift 3.0

 @IBAction func touchUpInside(_ sender: UIButton) { let alertController = UIAlertController(title: "", message: "", prefernetworkingStyle: .alert) //to change font of title and message. let titleFont = [NSFontAttributeName: UIFont(name: "ArialHebrew-Bold", size: 18.0)!] let messageFont = [NSFontAttributeName: UIFont(name: "Avenir-Roman", size: 12.0)!] let titleAttrString = NSMutableAttributedString(string: "Title Here", attributes: titleFont) let messageAttrString = NSMutableAttributedString(string: "Message Here", attributes: messageFont) alertController.setValue(titleAttrString, forKey: "attributedTitle") alertController.setValue(messageAttrString, forKey: "attributedMessage") let action1 = UIAlertAction(title: "Action 1", style: .default) { (action) in print("\(action.title)") } let action2 = UIAlertAction(title: "Action 2", style: .default) { (action) in print("\(action.title)") } let action3 = UIAlertAction(title: "Action 3", style: .default) { (action) in print("\(action.title)") } let okAction = UIAlertAction(title: "Ok", style: .default) { (action) in print("\(action.title)") } alertController.addAction(action1) alertController.addAction(action2) alertController.addAction(action3) alertController.addAction(okAction) alertController.view.tintColor = UIColor.blue alertController.view.backgroundColor = UIColor.black alertController.view.layer.cornerRadius = 40 present(alertController, animated: true, completion: nil) } 

Salida

Fuente personalizada, tamaño y color de UIAlertController

Use el protocolo UIAppearance . Ejemplo para configurar una fuente: cree una categoría para extender UILabel :

 @interface UILabel (FontAppearance) @property (nonatomic, copy) UIFont * appearanceFont UI_APPEARANCE_SELECTOR; @end @implementation UILabel (FontAppearance) -(void)setAppearanceFont:(UIFont *)font { if (font) [self setFont:font]; } -(UIFont *)appearanceFont { return self.font; } @end 

Y su uso:

 UILabel * appearanceLabel = [UILabel appearanceWhenContainedIn:UIAlertController.class, nil]; [appearanceLabel setAppearanceFont:[UIFont boldSystemFontOfSize:10]]; //for example 

Probé y trabajo con el estilo UIAlertControllerStyleActionSheet , pero supongo que también funcionará con UIAlertControllerStyleAlert .

PS Mejor control de disponibilidad de class en lugar de versión de iOS:

 if ([UIAlertController class]) { // UIAlertController code (iOS 8) } else { // UIAlertView code (pre iOS 8) } 

Lo estoy usando.

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

Agregue una línea (AppDelegate) y funcione para todo UIAlertController.

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.

Otras soluciones presentadas dependen de que la jerarquía de vista permanezca estática, algo que Apple detesta hacer. Espere que esas soluciones fallen en versiones futuras de iOS.

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. También es completamente independiente con respecto a la jerarquía de vistas de las vistas secundarias del UIAlertController.

Feliz hacking!

Solución / Hack para iOS9

  UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Test Error" message:@"This is a test" prefernetworkingStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { NSLog(@"Alert View Displayed"); [[[[UIApplication shanetworkingApplication] delegate] window] setTintColor:[UIColor whiteColor]]; }]; [alertController addAction:cancelAction]; [[[[UIApplication shanetworkingApplication] delegate] window] setTintColor:[UIColor blackColor]]; [self presentViewController:alertController animated:YES completion:^{ NSLog(@"View Controller Displayed"); }]; 

Acabo de completar un reemploop para UIAlertController . Este es el único path sensato, creo:


Antiguo

Aquí está mi método en Swift, que mezcla una gran cantidad de información de las respuestas aquí.

 func changeAlert(alert: UIAlertController, backgroundColor: UIColor, textColor: UIColor, buttonColor: UIColor?) { let view = alert.view.firstSubview().firstSubview() view.backgroundColor = backgroundColor view.layer.cornerRadius = 10.0 // set color to UILabel font setSubviewLabelsToTextColor(textColor, view: view) // set font to alert via KVC, otherwise it'll get overwritten let titleAttributed = NSMutableAttributedString( string: alert.title!, attributes: [NSFontAttributeName:UIFont.boldSystemFontOfSize(17)]) alert.setValue(titleAttributed, forKey: "attributedTitle") let messageAttributed = NSMutableAttributedString( string: alert.message!, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(13)]) alert.setValue(messageAttributed, forKey: "attributedMessage") // set the buttons to non-blue, if we have buttons if let buttonColor = buttonColor { alert.view.tintColor = buttonColor } } func setSubviewLabelsToTextColor(textColor: UIColor, view:UIView) { for subview in view.subviews { if let label = subview as? UILabel { label.textColor = textColor } else { setSubviewLabelsToTextColor(textColor, view: subview) } } } 

Esto funciona perfectamente en algunas situaciones, y en otros es un error total (los colors de tinte no se muestran como se esperaba).

Puede usar una biblioteca externa como PMAlertController sin utilizar una solución alternativa, donde puede sustituir el UIAlertController no personalizado de Apple con una alerta super personalizable.

Compatible con Xcode 8, Swift 3 y Objective-C

Ejemplo de PMAlertController

caracteristicas:

  • [x] Vista de encabezado
  • [x] Imagen del encabezado (opcional)
  • [x] Título
  • [x] Mensaje de descripción
  • [x] Personalizaciones: fonts, colors, dimensiones y más
  • [x] 1, 2 botones (horizontalmente) o 3+ botones (verticalmente)
  • [x] Cierre cuando se presiona un button
  • [x] Soporte de campos de text
  • [x] Implementación similar a UIAlertController
  • [x] Cocoapods
  • [x] Cartago
  • [x] Animación con UIKit Dynamics
  • [x] Compatibilidad con Objective-C
  • [x] Swift 2.3 y Swift 3 son compatibles.

Yo trabajo para Urban Outfitters. Tenemos un pod de código abierto, URBNAlert , que usamos en todas nuestras aplicaciones. Está basado en UIAlertController , pero es altamente personalizable.

La fuente está aquí: https://github.com/urbn/URBNAlert

O simplemente instálelo por la cápsula colocando URBNAlert en su Podfile

Aquí hay un código de ejemplo:

 URBNAlertViewController *uac = [[URBNAlertViewController alloc] initWithTitle:@"The Title of my message can be up to 2 lines long. It wraps and centers." message:@"And the message that is a bunch of text. And the message that is a bunch of text. And the message that is a bunch of text."]; // You can customize style elements per alert as well. These will override the global style just for this alert. uac.alertStyler.blurTintColor = [[UIColor orangeColor] colorWithAlphaComponent:0.4]; uac.alertStyler.backgroundColor = [UIColor orangeColor]; uac.alertStyler.textFieldEdgeInsets = UIEdgeInsetsMake(0.0, 15.0, 0.0, 15.0); uac.alertStyler.titleColor = [UIColor purpleColor]; uac.alertStyler.titleFont = [UIFont fontWithName:@"Chalkduster" size:30]; uac.alertStyler.messageColor = [UIColor blackColor]; uac.alertStyler.alertMinWidth = @150; uac.alertStyler.alertMaxWidth = @200; // many more styling options available [uac addAction:[URBNAlertAction actionWithTitle:@"Ok" actionType:URBNAlertActionTypeNormal actionCompleted:^(URBNAlertAction *action) { // Do something }]]; [uac addAction:[URBNAlertAction actionWithTitle:@"Cancel" actionType:URBNAlertActionTypeCancel actionCompleted:^(URBNAlertAction *action) { // Do something }]]; [uac show]; 

Por favor encuentre esta categoría. Puedo cambiar FONT y Color of UIAlertAction y UIAlertController.

Utilizar:

 UILabel * appearanceLabel = [UILabel appearanceWhenContainedIn:UIAlertController.class, nil]; [appearanceLabel setAppearanceFont:yourDesireFont]]; 

Un poco torpe, pero esto me funciona ahora mismo para establecer colors de background y de text. Lo encontré aquí .

 UIView * firstView = alertController.view.subviews.firstObject; UIView * nextView = firstView.subviews.firstObject; nextView.backgroundColor = [UIColor blackColor]; 

Para cambiar el color de un button como CANCELAR al color rojo, puede usar esta propiedad de estilo llamada UIAlertActionStyle.destructive:

 let prompt = UIAlertController.init(title: "Reset Password", message: "Enter Your E-mail :", prefernetworkingStyle: .alert) let okAction = UIAlertAction.init(title: "Submit", style: .default) { (action) in //your code } let cancelAction = UIAlertAction.init(title: "Cancel", style: UIAlertActionStyle.destructive) { (action) in //your code } prompt.addTextField(configurationHandler: nil) prompt.addAction(okAction) prompt.addAction(cancelAction) present(prompt, animated: true, completion: nil); 

He creado un método objective-C

 -(void)customAlertTitle:(NSString*)title message:(NSString*)message{ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:nil cancelButtonTitle:@"NO" otherButtonTitles:@"YES", nil]; UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 80)]; UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 270, 50)]; titleLabel.text = title; titleLabel.font = [UIFont boldSystemFontOfSize:20]; titleLabel.numberOfLines = 2; titleLabel.textColor = [UIColor networkingColor]; titleLabel.textAlignment = NSTextAlignmentCenter; [subView addSubview:titleLabel]; UILabel *messageLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 30, 270, 50)]; messageLabel.text = message; messageLabel.font = [UIFont systemFontOfSize:18]; messageLabel.numberOfLines = 2; messageLabel.textColor = [UIColor networkingColor]; messageLabel.textAlignment = NSTextAlignmentCenter; [subView addSubview:messageLabel]; [alertView setValue:subView forKey:@"accessoryView"]; [alertView show]; } 

Código wokring perfectamente en Xcode 8.3.1. Puede personalizar según el requisito.