美文网首页
Swift 封装UIAlertController

Swift 封装UIAlertController

作者: NicWhite | 来源:发表于2019-10-23 16:05 被阅读0次

    UIAlertController是苹果iOS 8以后推出的弹窗视图,其用来取代UIAlertView,官方也建议在iOS 9之后弃用后者,
    前者相比后者来说写法简单易懂,但是代码仍算比较多,所以我使用了block的方式将其简化封装,方便全局和多次使用。也方便以后各种替换这个弹窗。

    特意也使用@objc 来提供给OC使用,这样就清爽多啦。

    其中也添加了适配iPad的代码。

    先来看看使用效果:

    // Sheet
    let alertController = WSAlertController.alertSheet(title: "Sheet").add(title: "title1", style: .default) {
        // your code
    }.add(title: "title2", style: .destructive) {
        // your code        
    }.add(title: "title3", style: .cancel) {
       // your code         
    }.finish()
    
    // Alert
    let alertController = WSAlertController.alertAlert(title: "title", message: "message", okTitle: "ok", cancelTitle: "cancel") {
        // your code 
    }
    
    // Input
    let alertController = WSAlertController.alertInputViews(title: "title", message: "message", placeholders: ["请输入账号","请输入密码"]) { (inputTextArray) in
        // your code
    }
    

    是不是简化了许多。

    具体代码:

    import UIKit
    
    ///可空的无参无返回值 Block
    typealias AlertCompleteOptional = (() -> Swift.Void)?
    class WSAlertController: NSObject{
        //MARK: 链式初始化方法
        private var title: String?
        private var actionArray: [(String,UIAlertAction.Style,AlertCompleteOptional)] = []
        
        init(title: String?) {
            self.title = title
        }
        
        /// 类方法初始化链式
        @objc class func alertSheet(title: String?) -> WSAlertController{
            return WSAlertController(title: title)
        }
        
        @discardableResult
        @objc func add(title: String, style: UIAlertAction.Style, complete: AlertCompleteOptional) -> WSAlertController{
            actionArray.append((title,style,complete))
            return self
        }
        
        @objc func finish() ->UIAlertController{
            return WSAlertController.alertControllerSheet(title: self.title, actionArray: self.actionArray)
        }
        
        /// 使用actionSheet样式的系统AlertControllerSheet封装
        ///
        /// - Parameters:
        ///   - title: 标题
        ///   - hitSender: 当为ipad设备时给予一个附着的控件
        ///   - actionArray: 每个action独立元组数组
        /// - Returns: 返回这个alertController用于显示出来
        private class func alertControllerSheet(title: String?,
                                                actionArray: [(String,UIAlertAction.Style,AlertCompleteOptional)]) -> UIAlertController{
            
            let alertVC = UIAlertController(title: title, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet)
            for action in actionArray{
                let alertAction = UIAlertAction(title: action.0, style: action.1, handler: { (_) in
                    action.2?()
                })
                alertVC.addAction(alertAction)
            }
            addPopPresenterView(alertVC: alertVC)
            return alertVC
        }
        
        
        //MARK: 类方法
        /// 返回alertController 有取消和确定按钮
        ///
        /// - Parameters:
        ///   - title: 标题
        ///   - message: 内容
        ///   - okTitle: 确定按钮的文字
        ///   - okComplete: 回调事件
        /// - Returns: alertController 实例
        @objc class func alertAlert(title: String?, message: String?, okTitle: String, cancelTitle: String? = nil, okComplete: AlertCompleteOptional) -> UIAlertController{
            
            let alertVC = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
            let alertAction = UIAlertAction(title: okTitle, style: .default, handler: { (_) in
                if okComplete != nil{
                    okComplete!()
                }
            })
            
            let cancel = UIAlertAction(title: cancelTitle ?? "取消", style: .cancel) { (alert: UIAlertAction) -> Void in
            }
            
            alertVC.addAction(alertAction)
            alertVC.addAction(cancel)
            addPopPresenterView(alertVC: alertVC)
            return alertVC
        }
        
        /// 返回alertController 仅确定按钮
        ///
        /// - Parameters:
        ///   - title: 标题
        ///   - message: 内容
        ///   - okTitle: 确定按钮的文字
        ///   - okComplete: 回调事件
        /// - Returns: alertController 实例
        @objc class func alertAlert(title: String?, message: String?, okTitle: String, okComplete: AlertCompleteOptional) -> UIAlertController{
            
            let alertVC = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
            let alertAction = UIAlertAction(title: okTitle, style: .default, handler: { (_) in
                if okComplete != nil{
                    okComplete!()
                }
            })
            alertVC.addAction(alertAction)
            addPopPresenterView(alertVC: alertVC)
            return alertVC
        }
        
        
        /// 多个输入框的alertController
        ///
        /// - Parameters:
        ///   - title: 标题
        ///   - message: 内容
        ///   - placeholders: 多少个提示文字 代表多少个框
        ///   - okComplete: 回调字符串数组 数组内容顺序是输入框的顺序
        public class func alertInputViews(title: String?,
                                          message: String?,
                                          placeholders: [String]?,
                                          okComplete: @escaping ((_ text: [String]) -> Void)) -> UIAlertController{
            let alertVC = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
            
            if let placeholderList = placeholders{
                for placeholder in placeholderList{
                    alertVC.addTextField { (textField) in
                        textField.placeholder = placeholder
                    }
                }
            }
            
            let okAction = UIAlertAction(title: "确定", style: UIAlertActionStyle.default) { (action) in
                if let textFields = alertVC.textFields{
                    var inputText: [String] = []
                    for textfield in textFields{
                        if let text = textfield.text{
                            inputText.append(text)
                        }
                    }
                    okComplete(inputText)
                }
            }
            let cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.cancel) { (action) in
            }
            alertVC.addAction(okAction)
            alertVC.addAction(cancelAction)
            addPopPresenterView(alertVC: alertVC)
            return alertVC
        }
        
        /// 适配iPad
        private class func addPopPresenterView(alertVC: UIAlertController){
            if UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad {
                let popPresenter = alertVC.popoverPresentationController
                if let keywindow = UIApplication.shared.keyWindow{
                    popPresenter?.sourceView = keywindow
                    if alertVC.preferredStyle == UIAlertControllerStyle.alert {
                        popPresenter?.sourceRect = CGRect(x: keywindow.width()/2, y:keywindow.height()/2, width: 0, height: 0)
                    }else {
                        popPresenter?.sourceRect = CGRect(x: keywindow.width()/2, y: keywindow.height(), width: 0, height: 0)
                    }
                    popPresenter?.permittedArrowDirections = []
                }
            }
        }
    
    }
    

    相关文章

      网友评论

          本文标题:Swift 封装UIAlertController

          本文链接:https://www.haomeiwen.com/subject/wfekvctx.html