Comment changer la couleur de fond du UIAlertController?

En raison du comportement étrange de UIActionSheet dans iOS 8, j'ai implémenté UIAlertController avec UIAction en tant que buttons. Je voudrais changer tout l'arrière-plan de l'UIAlertController. Mais je ne trouve aucun moyen de le faire.

Essayé même avec,

actionController.view.backgroundColor = [UIColor blackColor]; 

Mais ne m'a pas aidé. Toute consortingbution à cet égard sera appréciable.

Merci d'avance.

Vous devez approfondir quelques points de vue:

 let subview = actionController.view.subviews.first! as UIView let alertContentView = subview.subviews.first! as UIView alertContentView.backgroundColor = UIColor.blackColor() 

Et peut-être que vous voulez garder le rayon de coin original:

  alertContentView.layer.cornerRadius = 5; 

Désolé pour le "Swifting" mais je ne suis pas familier avec Objective-C. J'espère que c'est similaire.

Bien sûr, il est également important de changer la couleur du titre des actions. Malheureusement, je ne sais pas, comment définir la couleur des actions séparément. Mais ceci est, comment vous changez toutes les colors de text de button:

 actionController.view.tintColor = UIColor.whiteColor(); 

MODIFIER:

Le rayon du coin du UIAlertController a changé depuis que cette réponse a été postée! Remplacez ceci:

  alertContentView.layer.cornerRadius = 5; 

pour ça:

  actionContentView.layer.cornerRadius = 15 

J'ai trouvé une manière hack-ish de le faire. D'abord, vous avez besoin d'une extension pour vous permettre de searchr l' UIVisualEffectView dans UIAlertController :

 extension UIView { func searchVisualEffectsSubview() -> UIVisualEffectView? { if let visualEffectView = self as? UIVisualEffectView { return visualEffectView } else { for subview in subviews { if let found = subview.searchVisualEffectsSubview() { return found } } } return nil } } 

Important : Vous devez appeler cette fonction après avoir appelé presentViewController , car ce n'est qu'après avoir chargé le controller de vue que la vue des effets visuels est insérée. Ensuite, vous pouvez changer l'effet associé à un effet de flou sombre:

 self.presentViewController(actionController, animated: true, completion: nil) if let visualEffectView = actionController.view.searchVisualEffectsSubview() { visualEffectView.effect = UIBlurEffect(style: .Dark) } 

Et voici le résultat final:

photo de démonstration

Je suis honnêtement surpris moi-même à quel point ça marche! Je pense que c'est probablement quelque chose que Apple a oublié d'append. De plus, je n'ai pas encore réussi à passer une application avec ce "hack" (ce n'est pas un hack car nous n'utilisons que des API publiques), mais je suis sûr qu'il n'y aura pas de problème.

Peut-être que vous aimez l'utilisation de l'effet de flou dans le mode sombre. Voici un moyen très simple d'get ceci:

 UIVisualEffectView.appearance(whenContainedInInstancesOf: [UIAlertController.classForCoder() as! UIAppearanceContainer.Type]).effect = UIBlurEffect(style: .dark) 
 func Alert(View: ViewController, Title: Ssortingng, TitleColor: UIColor, Message: Ssortingng, MessageColor: UIColor, BackgroundColor: UIColor, BorderColor: UIColor, ButtonColor: UIColor) { let TitleSsortingng = NSAtsortingbutedSsortingng(ssortingng: Title, atsortingbutes: [NSFontAtsortingbuteName : UIFont.systemFontOfSize(15), NSForegroundColorAtsortingbuteName : TitleColor]) let MessageSsortingng = NSAtsortingbutedSsortingng(ssortingng: Message, atsortingbutes: [NSFontAtsortingbuteName : UIFont.systemFontOfSize(15), NSForegroundColorAtsortingbuteName : MessageColor]) let alertController = UIAlertController(title: Title, message: Message, preferredStyle: .Alert) alertController.setValue(TitleSsortingng, forKey: "atsortingbutedTitle") alertController.setValue(MessageSsortingng, forKey: "atsortingbutedMessage") let okAction = UIAlertAction(title: "OK", style: .Default) { (action) in } let cancelAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil) alertController.addAction(okAction) alertController.addAction(cancelAction) let subview = alertController.view.subviews.first! as UIView let alertContentView = subview.subviews.first! as UIView alertContentView.backgroundColor = BackgroundColor alertContentView.layer.cornerRadius = 10 alertContentView.alpha = 1 alertContentView.layer.borderWidth = 1 alertContentView.layer.borderColor = BorderColor.CGColor //alertContentView.tintColor = UIColor.whiteColor() alertController.view.tintColor = ButtonColor View.presentViewController(alertController, animated: true) { // ... } } 

Swift3

Étape en une couche de plus comparer avec swift2

  let subview1 = alert.view.subviews.first! as UIView let subview2 = subview1.subviews.first! as UIView let view = subview2.subviews.first! as UIView subview.backgroundColor = backgroundColor 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 titleAtsortingbuted = NSMutableAtsortingbutedSsortingng( ssortingng: alert.title!, atsortingbutes: [NSFontAtsortingbuteName:UIFont.boldSystemFont(ofSize: 17)]) alert.setValue(titleAtsortingbuted, forKey: "atsortingbutedTitle") let messageAtsortingbuted = NSMutableAtsortingbutedSsortingng( ssortingng: alert.message!, atsortingbutes: [NSFontAtsortingbuteName:UIFont.systemFont(ofSize: 13)]) alert.setValue(messageAtsortingbuted, forKey: "atsortingbutedMessage") // set the buttons to non-blue, if we have buttons if let buttonColor = buttonColor { alert.view.tintColor = buttonColor } 

Voici une extension UIAlertController qui fonctionne à la fois sur iPad et sur iPhone. Le button Annuler passera automatiquement d'une couleur foncée à une couleur blanche en fonction de ce que blurStyle est sélectionné:

 extension UIAlertController { private struct AssociatedKeys { static var blurStyleKey = "UIAlertController.blurStyleKey" } public var blurStyle: UIBlurEffectStyle { get { return objc_getAssociatedObject(self, &AssociatedKeys.blurStyleKey) as? UIBlurEffectStyle ?? .extraLight } set (style) { objc_setAssociatedObject(self, &AssociatedKeys.blurStyleKey, style, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) view.setNeedsLayout() view.layoutIfNeeded() } } public var cancelButtonColor: UIColor? { return blurStyle == .dark ? UIColor(red: 28.0/255.0, green: 28.0/255.0, blue: 28.0/255.0, alpha: 1.0) : nil } private var visualEffectView: UIVisualEffectView? { if let presentationController = presentationController, presentationController.responds(to: Selector(("popoverView"))), let view = presentationController.value(forKey: "popoverView") as? UIView // We're on an iPad and visual effect view is in a different place. { return view.recursiveSubviews.flatMap({$0 as? UIVisualEffectView}).first } return view.recursiveSubviews.flatMap({$0 as? UIVisualEffectView}).first } private var cancelActionView: UIView? { return view.recursiveSubviews.flatMap({$0 as? UILabel}).first(where: {$0.text == "Cancel"})?.superview?.superview } public convenience init(title: Ssortingng?, message: Ssortingng?, preferredStyle: UIAlertControllerStyle, blurStyle: UIBlurEffectStyle) { self.init(title: title, message: message, preferredStyle: preferredStyle) self.blurStyle = blurStyle } open override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() visualEffectView?.effect = UIBlurEffect(style: blurStyle) cancelActionView?.backgroundColor = cancelButtonColor } } 

L'extension UIView suivante est également nécessaire:

 extension UIView { var recursiveSubviews: [UIView] { var subviews = self.subviews.flatMap({$0}) subviews.forEach { subviews.append(contentsOf: $0.recursiveSubviews) } return subviews } } 

Exemple:

 let controller = UIAlertController(title: "Dark Alert Controller", message: nil, preferredStyle: .actionSheet, blurStyle: .dark) // Setup controller actions etc... present(controller, animated: true, completion: nil) 

iPhone:

entrez la description de l'image ici

iPad:

entrez la description de l'image ici

pour Swift 3 Xcode 8.2.1

 let subview =(alert.view.subviews.first?.subviews.first?.subviews.first!)! as UIView subview.backgroundColor = UIColor(red: (145/255.0), green: (200/255.0), blue: (0/255.0), alpha: 1.0) alert.view.tintColor = UIColor.black 

entrez la description de l'image ici .

Pour Objective – C Code peut être comme.

 UIAlertController * alert=[UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert]; UIView *firstSubview = alert.view.subviews.firstObject; UIView *alertContentView = firstSubview.subviews.firstObject; for (UIView *subSubView in alertContentView.subviews) { subSubView.backgroundColor = [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f]; } UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action){ //Close Action }]; [alert addAction:cancelAction]; [self presentViewController:alert animated:YES completion:nil]; 

Vous pouvez utiliser le proxy d'apparence.

 [[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setBackgroundColor:[UIColor blackColor]]; 

Cela semble s'appliquer à tout sauf à l'action d'annulation lors de la présentation d'une feuille d'action.