Sample project -> 包含最新代码
第一步:
找到具有正确框架的子视图!
这个小函数将返回所有嵌套子视图的框架和地址。
我们正在寻找一个高度小于UIAlertController 并且具有Origin 的0,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 以便能够使用我们之前打印的地址之一获取子视图。使用guard或if 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设置颜色。