Swift显示警报最佳实践

Rya*_*ski 27 xcode ios uialertcontroller

我的应用程序中有各种控制器都需要验证,当验证失败时,我想显示带有错误的警报.这样做有一些最佳实践/设计模式吗?我可以简单地在Helper类中创建一个静态函数,如下所示:

static func displayAlert(message: String, buttonTitle: String, vc: UIViewController)
{
    let alertController = UIAlertController(title: "", message: message, preferredStyle: .Alert)

    let OKAction = UIAlertAction(title: buttonTitle, style: .Default, handler: nil)
    alertController.addAction(OKAction)

    vc.presentViewController(alertController, animated: true, completion: nil)
}
Run Code Online (Sandbox Code Playgroud)

但后来我需要传递视图控制器..这似乎是不好的做法.我可以拍摄通知并观察它,但这似乎有点矫枉过正.我是否在思考这个问题,还是有更多可接受的方法来处理这样的事情?

Rya*_*ski 54

我最终为UIViewController创建了一个扩展,并在那里创建了alert函数:

extension UIViewController {
  func alert(message: String, title: String = "") {
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
    let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
    alertController.addAction(OKAction)
    self.present(alertController, animated: true, completion: nil)
  }  
}
Run Code Online (Sandbox Code Playgroud)


Sig*_*gex 26

斯威夫特4

在这里,我想要这个,所以我做了一个完整的扩展.因此,在项目名称中创建一个新的swift文件,它可以放置以下代码.

import UIKit

extension UIViewController {

    func presentAlertWithTitle(title: String, message: String, options: String..., completion: @escaping (Int) -> Void) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        for (index, option) in options.enumerated() {
            alertController.addAction(UIAlertAction.init(title: option, style: .default, handler: { (action) in
                completion(index)
            }))
        }
        self.present(alertController, animated: true, completion: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后使用它,这么多人实际上没有显示哪些可能导致像我这样的新手混淆.

presentAlertWithTitle(title: "Test", message: "A message", options: "1", "2") { (option) in
    print("option: \(option)")
    switch(option) {
        case 0:
            print("option one")
            break
        case 1:
            print("option two")
        default:
            break
    }
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*bst 12

作为来自itstrueimryan的原始答案,请访问/sf/answers/2150010061/

Swift 3更新:

extension UIViewController {

    func alert(message: String, title: String = "") {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        alertController.addAction(OKAction)
        self.present(alertController, animated: true, completion: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)


Rya*_*ski 5

我可能已经通过 Krakendev 的一篇文章找到了这个问题的更好答案:https ://krakendev.io/blog/subclassing-can-suck-and-heres-why 。

这个想法是使用面向协议的编程来为 UIViewControllers 创建一个警报的默认实现:

protocol Alertable {
    func issueAlert()
}

extension Alertable where Self: UIViewController {
    func issueAlert() {
        // alert code here
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,就像那样,每个遵循 Alertable 的 UIViewController 都可以使用 issueAlert() 方法,甚至不必定义自己的实现。

当然,我们也可以为 issueAlert 函数定义参数:

extension Alertable where Self: UIViewController {
    func issueAlert(title: "Default Title", message: String = "Default Message") {
        // alert code here
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我们的视图控制器可以做到:

issueAlert()
Run Code Online (Sandbox Code Playgroud)

或者

issueAlert(title: "Error", message: "Something went wrong")
Run Code Online (Sandbox Code Playgroud)

我能想到的这种方法的两个优点是,只需查看类定义中的 Alertable 协议,您就知道视图控制器是否可以访问此方法,并且各个视图控制器如果想提供自定义功能,则可以覆盖此方法. 当然,现在你也可以指定 Alertable 合约作为方法参数。

  • 我知道现在有点晚了,但不。这很可能是最糟糕的方法,您发布的文章对于大型应用程序/系统来说是完全禁止的。在这种情况下,您希望开发人员现在搜索所有视图控制器类并将 `Alertable` 附加到它们,并希望其他开发人员也这样做,这是完全不可接受的。下一个问题是,一旦您实现自定义对话框,您将需要检查顶部控制器,例如`navigationController ?? self` 现在会破坏您的协议使用。最简单的是创建 UIViewController 扩展,最好是 OP 所做的。 (2认同)