【问题标题】:Change background color of title (only) in UIAlertController在 UIAlertController 中更改标题的背景颜色(仅)
【发布时间】:2015-10-28 02:52:35
【问题描述】:

我在How to change the background color of the UIAlertController? 中找到了以下代码来更改UIAlertView 的背景颜色:

let subview = dialog.view.subviews.first! as UIView
let alertContentView = subview.subviews.first! as UIView
subview.subviews.top!
alertContentView.backgroundColor = UIColor.whiteColor()

但是,它会改变整个视图的背景颜色。如何只更改标题的背景颜色?

【问题讨论】:

  • 您有机会查看答案吗?
  • @RMenke 我已经检查了 abhinav 解决方案,但这不是我正在寻找的答案。它改变了前景标题,而不是背景
  • 更新的答案没有子类化。
  • @RMenke 有帮助,谢谢伙计:'D
  • 不客气,这是一个棘手的难题

标签: ios swift uialertcontroller


【解决方案1】:

试试这个:

let alertController = UIAlertController(title: "", message: "myMessage", preferredStyle: .Alert)

let attributedString = NSAttributedString(string: "myTitle", attributes: [
    NSFontAttributeName : UIFont.systemFontOfSize(15),
    NSForegroundColorAttributeName : UIColor.redColor()
    ])

alertController.setValue(attributedString, forKey: "attributedTitle")

【讨论】:

  • 这会改变前景色,而不是背景色。
【解决方案2】:

尝试为我关注它的作品。

 let confirmAlert = UIAlertController(title: "Application Name", message: "This is demo message.", preferredStyle: .Alert)

        let attributedString = NSAttributedString(string: "Application Name", attributes: [
            NSFontAttributeName : UIFont.systemFontOfSize(13),
            NSForegroundColorAttributeName : UIColor.greenColor()
            ])
        let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
        confirmAlert.addAction(defaultAction)

        confirmAlert.setValue(attributedString, forKey: "attributedTitle")
        UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(confirmAlert, animated: true, completion: nil)

【讨论】:

    【解决方案3】:

    Sample project -> 包含最新代码

    第一步:

    找到具有正确框架的子视图!

    这个小函数将返回所有嵌套子视图的框架和地址。

    我们正在寻找一个高度小于UIAlertController 并且具有Origin0,0 的子视图。 我的 alertController 的高度是128

    func subViewStack(view:UIView, levels: [Int]) {
    
        var currentLevels = levels
        currentLevels.append(0)
    
        for i in 0..<view.subviews.count {
    
            currentLevels[currentLevels.count - 1] = i
    
            let subView = view.subviews[i]
            print(subView.frame, "depth:", currentLevels)
            subViewStack(subView, levels: currentLevels)
    
        }
    
    }
    

    这会打印如下内容:

    (0.0, 0.0, 270.0, 128.0) depth: [0, 0]
    
    //frame - firstsubview - firstsubview
    

    这可能是一个不错的候选:

    (0.0, 0.0, 270.0, 84.0) depth: [0, 1, 0, 0]
    //frame - firstsubview - secondsubiew - firstsubview - firstsubview
    

    翻译成这样:

    print(alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].frame)
    // prints (0.0, 0.0, 270.0, 84.0) -> Bingo!
    

    第二步:

    为该子视图着色!

    alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].backgroundColor = UIColor.redColor()
    

    如果你在呈现 alertController 之前设置颜色,它会崩溃。 在 completionHandler 中设置它是有效的。

    presentViewController(alertController, animated: true) { () -> Void in
    
        self.subViewStack(alertController.view, levels: [])
        print(alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].frame)
        alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].backgroundColor = UIColor.redColor()
    
    }
    

    第三步

    确保安全! 如果他们对堆栈进行了任何更改,这将防止您的应用程序崩溃。您的视图可能没有着色,但崩溃更严重。

    扩展 UIView 以便能够使用我们之前打印的地址之一获取子视图。使用guardif let来防止访问不存在的子视图。

    extension UIView {
    
        // use the printed addresses to access the views. This is safe even if the UIView changes in an update.
        func getSubView(withAddress address:[Int]) -> UIView? {
    
            var currentView : UIView = self
    
            for index in address {
    
                guard currentView.subviews.count > index else {
                    return nil
                }
                currentView = currentView.subviews[index]
    
            }
            return currentView
        }
    }
    

    第四步:

    由于不允许继承UIAlertController,我们可能会尝试扩展它。这不会让您访问viewDidAppear,因此您无法显示UIAlertController 动画。

    protocol CustomAlert {
    
        var view : UIView! { get }
    
    }
    
    extension CustomAlert {
    
        func titleBackgroundColor(color:UIColor) {
    
            if view == nil {
                return
            }
    
            if let titleBackground = view.getSubView(withAddress: [0, 1, 0, 0]) {
                titleBackground.backgroundColor = color
            }
        }
    }
    
    extension UIAlertController : CustomAlert {
    
    }
    

    这为您提供了查找您可能想要更改的任何子视图的方法以及为该类添加自定义函数的方法。没有子类化。

    presentViewController的completionHandler中调用titleBackgroundColor设置颜色。

    【讨论】:

    • 可以扩展 UIAlertController 吗?正如在苹果类参考中指出你不应该扩展这个类,developer.apple.com/library/ios/documentation/UIKit/Reference/…
    • @Christoper 不,这不行。但这是可能的。我不知道这是如何通过应用程序审查的。如果您不显示 alertcontroller 动画,您可以在完成处理程序中为背景着色,然后您不需要对其进行子类化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-07
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多