【问题标题】:UIViewController and inheritanceUIViewController 和继承
【发布时间】:2017-12-12 06:26:25
【问题描述】:

我的应用程序中有多个视图控制器。在它们中的每一个中,我都必须根据某些条件显示警报。我没有在每个控制器中添加警报控制器,而是尝试使用继承,如下所示。

UIExtension.swift

class UIExtension: UIViewController {

    func prepareAlert(title: String, message: String) -> UIAlertController {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
        return alert
    }

}

FirstViewController.swift

class FirstViewController: UIExtension {

    //somewhere inside used the following
    present(prepareAlert(title: "Error Validation", message: "invalid fields"), animated: true, completion: nil)

}

同样,在其他视图控制器中使用 UIExtension 来显示警报。推荐这种方式吗?

【问题讨论】:

    标签: ios swift inheritance uiviewcontroller


    【解决方案1】:

    对于这样的事情,最好将 prepareAlert 方法添加到 UIViewController 扩展。不需要子类化。

    extension UIViewController {
        func prepareAlert(title: String, message: String) -> UIAlertController {
            let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
            return alert
        }
    }
    

    然后你的视图控制器:

    class FirstViewController: UIViewController {
        //somewhere inside used the following
        present(prepareAlert(title: "Error Validation", message: "invalid fields"), animated: true, completion: nil)
    }
    

    这允许您从任何视图控制器使用prepareAlert,包括UITableViewControllerUICollectionViewController 等。

    【讨论】:

      【解决方案2】:

      该方法在技术上是正确的,尽管如果您考虑扩展所有 UIViewController 实例,而不管任何条件,那么直接扩展它会更方便:

      extension UIViewController {
          func prepareAlert(title: String, message: String) -> UIAlertController {
              let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
              alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
              return alert
          }
      }
      

      rmaddy 更快。但我决定不删除答案,而是添加另一个想法。

      另一种方法是使用协议作为某些功能的包装器,这也被广泛使用。

      假设您有一个协议,与某些功能相关联,例如生成警报,在这种情况下:

      protocol Alertable {} // or whatever else name
      
      extension Alertable {
          func prepareAlert(title: String, message: String) -> UIAlertController {
              let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
              alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
              return alert
          }
      }
      

      然后,当您希望某个 UIViewController 实例(或任何其他类,您明白了)与此功能相关联时,只需执行以下操作:

      class FirstViewController: UIViewController, Alertable {
         // Now you can do the same:
      
          present(prepareAlert(title: "Error Validation", message: "invalid fields"), animated: true, completion: nil)
      
      }
      

      总而言之,组成一个协议并对其进行扩展,然后将某些类与它相关联——以公开该功能——是一种非常方便和有用的做法。特别是,这是封装某些功能的好方法,例如,如果您不是指全局/类范围的访问权限。

      【讨论】:

        【解决方案3】:

        我与您分享的一些扩展方法在大多数应用程序中经常使用,您可以在UIViewController 类的任何地方使用它并享受:)

        extension UIViewController {
            let kAPPNAME = "Your App name"
        
            func showOkAlert(_ msg: String) {
                let alert = UIAlertController(title:
                    kAPPNAME, message: msg, preferredStyle: .alert)
                let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
                alert.addAction(okAction)
                present(alert, animated: true, completion: nil)
            }
        
            func showOkAlertWithHandler(_ msg: String,handler: @escaping ()->Void){
                let alert = UIAlertController(title: kAPPNAME, message: msg, preferredStyle: .alert)
                let okAction = UIAlertAction(title: "OK", style: .default) { (type) -> Void in
                    handler()
                }
                alert.addAction(okAction)
                present(alert, animated: true, completion: nil)
            }
        
            func showAlertWithActions(_ msg: String,titles:[String], handler:@escaping (_ clickedIndex: Int) -> Void) {
                let alert = UIAlertController(title: kAPPNAME, message: msg, preferredStyle: .alert)
                for title in titles {
                    let action  = UIAlertAction(title: title, style: .default, handler: { (alertAction) in
                        //Call back fall when user clicked
                        let index = titles.index(of: alertAction.title!)
                        if index != nil {
                            handler(index!+1)
                        }
                        else {
                            handler(0)
                        }
                    })
                    alert.addAction(action)
                }
                present(alert, animated: true, completion: nil)
            }
        
            func showOkCancelAlertWithAction(_ msg: String, handler:@escaping (_ isOkAction: Bool) -> Void) {
                let alert = UIAlertController(title: kAPPNAME, message: msg, preferredStyle: .alert)
                let okAction =  UIAlertAction(title: "OK", style: .default) { (action) -> Void in
                    return handler(true)
                }
                let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) -> Void in
                    return handler(false)
                }
                alert.addAction(cancelAction)
                alert.addAction(okAction)
                present(alert, animated: true, completion: nil)
            }
        }
        

        用途

        class FirstViewController: UIViewController {
               override func viewDidLoad() {
               super.viewDidLoad()
        
                //Only Info
                self.showOkAlert("Hello")
        
                //Info with Okay button
                self.showOkAlertWithHandler("Hello Again") {
                    print("Tap to Okay")
                }
        
                //Show alert with Okay and cancel
                self.showOkCancelAlertWithAction("Hello with Cancel") { (isOk) in
                    if isOk {
                        print("Okay")
                    }
                    else {
                        print("Cancel")
                    }
                }
        
                //Show alert with actions         
                self.showAlertWithActions("Hello with action", titles: ["Allow","Don't Allow", "Cancel"]) { (tapIndex) in
                    if tapIndex == 1 {
                        print("Allow")
                    }
                } 
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多