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 = []
}
}
}
}