Swift 中的 UIAlertView:5 个致命错误及如何避免

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么你的 UIAlertView 不工作(以及 Stack Overflow 有什么关系)

\n\n

如果你曾经搜索过“How would I create a UIAlertView in Swift?”——你并不孤单。这个 Stack Overflow 上的问题已经积累了数十万次浏览。看起来似乎很简单?向用户显示一个带有“确定”按钮的弹出窗口。但在实践中,新手(不仅仅是新手)经常会掉进同样的陷阱。

\n\n

在本文中,我们将分析在 Swift 中创建 UIAlertView 的 5 大错误,展示如何修复它们,并提供UIAlertController的现成代码——这是对已弃用 API 的现代替代方案。如果你想编写干净、无崩溃的工作代码,请继续阅读。

\n\n

错误 #1:使用 UIAlertView 而不是 UIAlertController

\n\n

最常见的错误是在现代 Swift 中尝试调用 UIAlertView。这个类早在 iOS 8 中就被标记为已弃用(deprecated)。如果你编写:

\n\n
let alert = UIAlertView(title: "错误", message: "出了点问题", delegate: nil, cancelButtonTitle: "确定")\nalert.show()
\n\n

……那么编译器很可能会发出警告或错误。即使项目编译成功,在 iOS 13+ 上弹窗也无法正常工作。

\n\n

为什么会这样?

\n

苹果早在 iOS 8 中就用 UIAlertController 替换了 UIAlertView。旧类不再受支持,使用它可能导致意外行为。

\n\n

如何修复?

\n

使用 UIAlertController,并指定首选样式为 .alert 或 .actionSheet。以下是正确的代码:

\n\n
let alert = UIAlertController(title: "错误",\n                              message: "出了点问题",\n                              preferredStyle: .alert)\nalert.addAction(UIAlertAction(title: "确定", style: .default))\npresent(alert, animated: true)
\n\n

请记住:在现代 Swift 中,UIAlertView 是遗留代码。始终使用 UIAlertController。

\n\n

错误 #2:忘记调用 present()

\n\n

即使你创建了 UIAlertController,但忘记显示它——什么也不会发生。字面意义上的。代码会执行,弹窗会在内存中创建,但用户看不到它。

\n\n

典型错误示例:

\n\n
func showAlert() {\n    let alert = UIAlertController(title: "你好", message: "世界", preferredStyle: .alert)\n    alert.addAction(UIAlertAction(title: "确定", style: .default))\n    // 忘记调用 present!\n}
\n\n

结果:一片寂静。没有错误,没有弹窗。你会纳闷为什么代码不工作。

\n\n

如何修复?

\n

始终在当前视图控制器上调用 present(_:animated:completion:):

\n\n
func showAlert() {\n    let alert = UIAlertController(title: "你好", message: "世界", preferredStyle: .alert)\n    alert.addAction(UIAlertAction(title: "确定", style: .default))\n    present(alert, animated: true, completion: nil)\n}
\n\n

提示:如果你在闭包或异步代码中调用弹窗,请确保 self(视图控制器)仍然存在。否则会导致崩溃。

\n\n

错误 #3:按钮点击处理不正确

\n\n

在旧的 UIAlertView 中,我们使用委托方法 alertView(_:clickedButtonAt:)。在 UIAlertController 中则完全不同——使用闭包(closures)。

\n\n

新手常常试图让类遵循 UIAlertViewDelegate 并实现委托方法,但这在 UIAlertController 中行不通。

\n\n

错误做法:

\n\n
class ViewController: UIViewController, UIAlertViewDelegate {\n    func showAlert() {\n        let alert = UIAlertController(title: "问题", message: "你同意吗?", preferredStyle: .alert)\n        alert.addAction(UIAlertAction(titl                

博客

书籍推荐