如何更改UIAlertController的背景颜色?

由于UIActionSheet在iOS 8中的奇怪行为,我已经使用UIAction实现了UIAlertController作为button。 我想改变UIAlertController的整个背景。 但我找不到任何方法来做到这一点。

甚至尝试过,

actionController.view.backgroundColor = [UIColor blackColor]; 

但是没有帮助我。 任何有关这方面的投入都是可观的。

提前致谢。

你必须深入一些看法:

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

也许你想保持原来的angular落半径:

  alertContentView.layer.cornerRadius = 5; 

对不起, “Swift”,但我不熟悉Objective-C。 我希望这是相似的。

当然,改变动作的标题颜色也很重要。 不幸的是,我不知道,如何分别设置行动的颜色。 但是,这是,你如何改变所有button的文字颜色:

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

编辑:

自这个答案发布以来, UIAlertController的圆angular半径已经改变! replace这个:

  alertContentView.layer.cornerRadius = 5; 

对此:

  actionContentView.layer.cornerRadius = 15 

我发现了一个黑客办法。 首先,您需要一个扩展来允许您searchUIVisualEffectViewUIAlertController

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

重要提示 :调用presentViewController ,必须调用该函数,因为只有在视图控制器加载视觉效果视图之后才能调用。 然后,您可以将与其关联的效果更改为黑暗模糊效果:

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

这是最后的结果:

演示图片

我真的很惊讶自己如何运作! 我认为这可能是苹果忘了添加的东西。 另外,我还没有通过这个“黑客”的批准通过一个应用程序(这不是一个黑客,因为我们只使用公共API),但我相信这不会有问题。

也许你喜欢在黑暗模式下使用模糊效果。 这是一个非常简单的方法来得到这个:

 UIVisualEffectView.appearance(whenContainedInInstancesOf: [UIAlertController.classForCoder() as! UIAppearanceContainer.Type]).effect = UIBlurEffect(style: .dark) 
 func Alert(View: ViewController, Title: String, TitleColor: UIColor, Message: String, MessageColor: UIColor, BackgroundColor: UIColor, BorderColor: UIColor, ButtonColor: UIColor) { let TitleString = NSAttributedString(string: Title, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(15), NSForegroundColorAttributeName : TitleColor]) let MessageString = NSAttributedString(string: Message, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(15), NSForegroundColorAttributeName : MessageColor]) let alertController = UIAlertController(title: Title, message: Message, preferredStyle: .Alert) alertController.setValue(TitleString, forKey: "attributedTitle") alertController.setValue(MessageString, forKey: "attributedMessage") 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

与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 titleAttributed = NSMutableAttributedString( string: alert.title!, attributes: [NSFontAttributeName:UIFont.boldSystemFont(ofSize: 17)]) alert.setValue(titleAttributed, forKey: "attributedTitle") let messageAttributed = NSMutableAttributedString( string: alert.message!, attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: 13)]) alert.setValue(messageAttributed, forKey: "attributedMessage") // set the buttons to non-blue, if we have buttons if let buttonColor = buttonColor { alert.view.tintColor = buttonColor } 

这是一个适用于iPad和iPhone的UIAlertController扩展。 取消button将自动从深色变成白色,具体取决于所选的blurStyle:

 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: String?, message: String?, 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 } } 

以下UIView扩展名也是需要的:

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

例:

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

苹果手机:

在这里输入图像说明

iPad的:

在这里输入图像说明

为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 

在这里输入图像说明

对于Objective – C代码可能会像。

 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]; 

您可以使用外观代理。

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

这似乎只适用于除作为一个行动表呈现的取消行动。