如何更改UIAlertController的背景颜色?

GJD*_*JDK 30 objective-c uiactionsheet ios uialertcontroller

由于UIActionSheet在iOS 8中的奇怪行为,我已经将UIAlertController与UIAction一起实现为按钮.我想改变UIAlertController的整个背景.但我找不到任何办法.

甚至尝试过,

actionController.view.backgroundColor = [UIColor blackColor];
Run Code Online (Sandbox Code Playgroud)

但是没有帮助我.关于这方面的任何意见都是值得注意的.

提前致谢.

小智 40

你必须深入了解一些观点:

let subview = actionController.view.subviews.first! as UIView
let alertContentView = subview.subviews.first! as UIView
alertContentView.backgroundColor = UIColor.blackColor()
Run Code Online (Sandbox Code Playgroud)

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

 alertContentView.layer.cornerRadius = 5;
Run Code Online (Sandbox Code Playgroud)

对不起"Swifting",但我不熟悉Objective-C.我希望这是类似的.

当然,更改动作的标题颜色也很重要.不幸的是我不知道,如何分别设置动作的颜色.但是,这是如何更改所有按钮文本颜色:

actionController.view.tintColor = UIColor.whiteColor();
Run Code Online (Sandbox Code Playgroud)

编辑:

自这个答案发布以来,UIAlertController的角半径已经改变了!替换这个:

 alertContentView.layer.cornerRadius = 5;
Run Code Online (Sandbox Code Playgroud)

对此:

 actionContentView.layer.cornerRadius = 15
Run Code Online (Sandbox Code Playgroud)

  • 这是Objective C版本:`UIView*firstView = alertController.view.subviews.firstObject; UIView*nextView = firstView.subviews.firstObject; nextView.backgroundColor = [UIColor greenColor];` (10认同)
  • 如果你是Swifting,那么分号是什么?!:) (5认同)
  • 这是什么版本的iOS?在11.3中似乎不起作用 (3认同)

Jea*_*ler 20

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

UIVisualEffectView.appearance(whenContainedInInstancesOf: [UIAlertController.classForCoder() as! UIAppearanceContainer.Type]).effect = UIBlurEffect(style: .dark)
Run Code Online (Sandbox Code Playgroud)

  • 对于取消按钮(仍为白色)不起作用。 (3认同)

Bru*_*ipe 16

我找到了一种破解方法.首先,您需要一个扩展名,以允许您搜索UIVisualEffectView内部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
    }
}
Run Code Online (Sandbox Code Playgroud)

重要提示:你必须调用此函数之后调用presentViewController,因为装载的视觉效果视图插入到位视图控制器后只.然后,您可以将与其关联的效果更改为暗模糊效果:

self.presentViewController(actionController, animated: true, completion: nil)

if let visualEffectView = actionController.view.searchVisualEffectsSubview()
{
    visualEffectView.effect = UIBlurEffect(style: .Dark)
}
Run Code Online (Sandbox Code Playgroud)

这是最终的结果:

演示图片

老实说我很惊讶它的工作原理!我想这可能是Apple忘记添加的内容.此外,我还没有通过与批准通过了一个应用这种"黑客"(这是不是黑客攻击,因为我们只使用公共API),但我相信不会有问题.


Sha*_*med 8

对于Swift 3/Swift 4

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
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述.


Mar*_*rke 6

这是UIAlertController可在iPad和iPhone上使用的扩展程序。取消按钮将根据选择的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 == actions.first(where: { $0.style == .cancel })?.title
        })?.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
    }
}
Run Code Online (Sandbox Code Playgroud)

UIView还需要以下扩展:

extension UIView {

    var recursiveSubviews: [UIView] {
        var subviews = self.subviews.flatMap({$0})
        subviews.forEach { subviews.append(contentsOf: $0.recursiveSubviews) }
        return subviews
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

let controller = UIAlertController(title: "Dark Alert Controller", message: nil, preferredStyle: .actionSheet, blurStyle: .dark)

// Setup controller actions etc...

present(controller, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

苹果手机:

在此处输入图片说明

iPad:

在此处输入图片说明


Lea*_*iao 5

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
    }
Run Code Online (Sandbox Code Playgroud)


小智 1

您可以使用外观代理。

[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setBackgroundColor:[UIColor blackColor]];
Run Code Online (Sandbox Code Playgroud)

当作为操作表呈现时,这似乎适用于除取消操作之外的所有操作。