Swift:自定义 UIAlertController 视图
Posted
技术标签:
【中文标题】Swift:自定义 UIAlertController 视图【英文标题】:Swift: Custom UIAlertController view 【发布时间】:2018-09-16 17:58:50 【问题描述】:docs 说子类化 UIAlertController 不好
UIAlertController 类旨在按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。
那么,推荐的警报方式是什么?不仅显示标题、消息和一些按钮,还显示进度条、列表等其他内容?
在我的特殊情况下,我希望有两种不同的警报,一种显示 ProgressBar,另一种显示错误消息列表。
目前我正在尝试手动添加 ProgressView 并设置约束:
func getProgressAlert(onAbort: @escaping () -> ()) -> UIAlertController
let alert = UIAlertController(title: "Test", message: "Test", preferredStyle: .alert)
let abort = UIAlertAction (title: "Abort", style: UIAlertActionStyle.cancel) _ in
onAbort()
alert.addAction(abort)
let margin:CGFloat = 8.0
let rect = CGRect(x:margin, y:72.0, width: alert.view.frame.width - margin * 2.0 , height:2.0)
self.progressView = UIProgressView(frame: rect)
self.progressView!.setProgress(0.0, animated: false)
self.progressView!.tintColor = UIColor.blue
alert.view.addSubview(self.progressView!)
self.progressView!.translatesAutoresizingMaskIntoConstraints = false
self.progressView!.widthAnchor.constraint(equalTo: alert.view.widthAnchor, multiplier: 1.0).isActive = true
self.progressView!.heightAnchor.constraint(equalToConstant: 5.0).isActive = true
self.progressView!.topAnchor.constraint(equalTo: alert.view.topAnchor).isActive = true
self.progressView!.leftAnchor.constraint(equalTo: alert.view.leftAnchor).isActive = true
return alert
我不认为这是应该这样做的方式,因为手动定义约束很容易在不同的设备上出错。例如,当前代码只是在警报视图顶部显示进度条,但我希望它显示在消息和中止按钮之间。
【问题讨论】:
推荐的方法是编写自己的自定义警报视图,而不是使用UIAlertController
。
是的,正如 rmaddy 所说,您只需要提供一个自定义视图控制器。查看 UIViewController.modelPresentationStyle 属性,它将帮助您覆盖自定义视图控制器,但您喜欢它。 ModalPresentationStyle
好吧,如果我理解正确的话,UIAlertController 只是 UIViewController 的一个特殊实现,它有一些默认元素,对吧?现在我应该定义我自己的继承自 UIViewController 的类,然后以模态方式呈现它,而不是使用 UIAlertController 并对其进行修改。
是的。查看此page 的“另请参阅”部分,以了解有关在呈现/关闭自定义视图控制器时可以做什么的更多信息。
【参考方案1】:
此类的视图层次结构是私有的,不得修改。
这几乎是这个 API 的致命一击。如果你尝试破解它,你会在尝试跨不同的 ios 版本支持它时给自己带来很多痛苦。
如果想要在警报上有自定义控件,您必须编写自定义 UIViewController
子类并在添加新功能时尽可能模仿 API(如果您不想这样做,将会有GitHub 上提供的示例)。
一些例子:
https://github.com/Codeido/PMAlertController https://github.com/Orderella/PopupDialog https://github.com/vikmeup/SCLAlertView-Swift https://github.com/sberrevoets/SDCAlertView【讨论】:
感谢您的回答。我没有使用您的示例,但我发现了一个非常好的库:github.com/SwiftKickMobile/SwiftMessages 非常适合我。谢谢:)【参考方案2】:文档确实不鼓励继承 UIAlertController。然而,很容易找到绕过这一点并将子视图偷偷摸摸到警报视图的示例,但他们这样做的风险是,iOS 小版本更新会破坏它。
Apple 设置此类限制的一个重要原因是,他们保留更改此类在幕后工作方式的权利。 UIAlertController 做了很多繁重的工作,它被许多应用程序使用,包括 Apple 提供的应用程序。
但它只做它该做的,而不做它不做的。我不认为 UIAlertController 不支持您描述的模态进度指示用例是偶然的。这些类型的 UI“障碍”与良好的用户体验相冲突。
有没有其他方法可以在不使用模式的情况下实现相同的目标?这可能涉及在工作完成之前禁用 UI 的其他方面,但仍允许用户导航。这将产生更好的用户体验。
但是,如果这对您不起作用,并且您必须使用路障模式进度指示器,承认它产生的负面用户体验,那么构建自己的会更加谨慎和可靠。 UIAlertController 没什么特别的,它和其他任何一个 UIViewController 一样。它使用publicly available API 来控制它的帧大小、它如何覆盖它的呈现视图以及它如何在屏幕上和屏幕外进行动画处理。只需滚动您自己,就可以省去很多麻烦。
【讨论】:
以上是关于Swift:自定义 UIAlertController 视图的主要内容,如果未能解决你的问题,请参考以下文章