系统的UIAlertController,在弹出时并没有动画效果,只是平静的展示在屏幕上,而且白底蓝字确实一斤能审美疲劳了,所以我想要自定义一个Alert。
参考了很多的开源,基本都是基于Frame来做布局,这样来做未免计算量会过于的大,显得繁杂,所以,我要试一下用AutoLayout来做。因为我可以通过AutoLayout的布局代码大概构想出页面的样式(前提是没有报错。。。),其实就是懒得算。先来看一下效果图
点击了"点我"按钮后,会在window上添加一个subController,同时subController上添加AlertView,并执行相应的动画。
调用方式
@objc func onClick() {
ML_Alert().show(title: "弹窗提示", message: "此处为弹窗消息内容", cancelButton: "取消", sureButton: "确认", sureOnClick: {
#if DEBUG
let pornHud = MBProgressHUD.showAdded(to: self.view, animated: true)
pornHud.mode = .text
pornHud.label.text = "按下了确认按钮"
pornHud.removeFromSuperViewOnHide = true
pornHud.hide(animated: true, afterDelay: 1.0)
pornHud.offset.y = screen_Height/2 - 120
#else
#endif
}) {
let pornHud = MBProgressHUD.showAdded(to: self.view, animated: true)
pornHud.mode = .text
pornHud.label.text = "按下了取消按钮"
pornHud.removeFromSuperViewOnHide = true
pornHud.hide(animated: true, afterDelay: 1.0)
pornHud.offset.y = screen_Height/2 - 120
}
}
功能部分
extension ML_Alert {
func show(title: String, message: String, cancelButton: String, sureButton: String, sureOnClick: @escaping ()->Void, cancelOnClick: @escaping ()->Void) {
print(cancelOnClick)
let window = UIApplication.shared.keyWindow
window?.addSubview(self.view)
window?.bringSubviewToFront(self.view)
self.view.frame = window!.frame
self.tipLabel.text = title
self.msgLabel.text = message
self.cancelButton.setTitle(cancelButton, for: .normal)
self.sureButton.setTitle(sureButton, for: .normal)
conY = NSLayoutConstraint.init(item: _alertView!, attribute: .centerY, relatedBy: .equal, toItem: self.view, attribute: .centerY, multiplier: 1, constant: -self.view.frame.height/2)
let conLeft = NSLayoutConstraint.init(item: _alertView!, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1, constant: 40)
let conRight = NSLayoutConstraint.init(item: _alertView!, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1, constant: -40)
NSLayoutConstraint.activate([conY,conLeft,conRight])
//设置布局后立即刷新布局,让控件放置在合适的位置
self.view.layoutIfNeeded()
UIView.animate(withDuration: 1.0, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: [], animations: {
self.conY.constant = 0
self.view.layoutIfNeeded()
}, completion: nil)
cancelBlock = cancelOnClick
sureBlock = sureOnClick
}
@objc func _onCancelClick() {
cancelBlock()
_dismiss()
}
@objc func _onSureClick() {
sureBlock()
_dismiss()
}
@objc func _dismiss() {
UIView.animate(withDuration: 0.4, animations: {
self.view.alpha = 0
}) { (isTrue) in
self.view.removeFromSuperview()
}
}
}
布局
class ML_Alert: UIViewController {
var cancelBlock: cancelResult_Block!
var sureBlock: sureResult_Block!
var _alertView: UIView!
var tipLabel: UILabel!
var msgLabel: UILabel!
var centerLine: UIView!
var cancelButton: UIButton!
var sureButton: UIButton!
var conY: NSLayoutConstraint!
var strongSelf: ML_Alert?//强引用,解决onClick不执行
init() {
super.init(nibName: nil, bundle: nil)
strongSelf = self
self.view.backgroundColor = UIColor.black.withAlphaComponent(0.4)
configUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configUI() {
_alertView = AlertView()
_alertView.useAutoLayout(useAutoLayout: true)
_alertView.backgroundColor = .white
_alertView.layer.cornerRadius = 10
self.view.addSubview(_alertView)
tipLabel = UILabel()
tipLabel.translatesAutoresizingMaskIntoConstraints = false
tipLabel.font = .systemFont(ofSize: 22, weight: .heavy)
tipLabel.numberOfLines = 0
tipLabel.textAlignment = .center
_alertView.addSubview(tipLabel)
msgLabel = UILabel()
msgLabel.translatesAutoresizingMaskIntoConstraints = false
msgLabel.font = .systemFont(ofSize: 15, weight: .regular)
msgLabel.numberOfLines = 0
msgLabel.textAlignment = .center
_alertView.addSubview(msgLabel)
centerLine = UIView()
centerLine.backgroundColor = .lightGray
centerLine.translatesAutoresizingMaskIntoConstraints = false
_alertView.addSubview(centerLine)
cancelButton = UIButton.init(type: .custom)
cancelButton.translatesAutoresizingMaskIntoConstraints = false
cancelButton.setTitleColor(.red, for: .normal)
cancelButton.addTarget(self, action: #selector(_onCancelClick), for: .touchUpInside)
cancelButton.isEnabled = true
_alertView.addSubview(cancelButton)
sureButton = UIButton.init(type: .custom)
sureButton.translatesAutoresizingMaskIntoConstraints = false
sureButton.setTitleColor(.black, for: .normal)
sureButton.addTarget(self, action: #selector(_onSureClick), for: .touchUpInside)
_alertView.addSubview(sureButton)
NSLayoutConstraint.init(item: tipLabel!, attribute: .top, relatedBy: .equal, toItem: _alertView, attribute: .top, multiplier: 1, constant: 18).isActive = true
NSLayoutConstraint.init(item: tipLabel!, attribute: .left, relatedBy: .equal, toItem: _alertView, attribute: .left, multiplier: 1, constant: 8).isActive = true
NSLayoutConstraint.init(item: tipLabel!, attribute: .right, relatedBy: .equal, toItem: _alertView, attribute: .right, multiplier: 1, constant: -8).isActive = true
NSLayoutConstraint.init(item: tipLabel!, attribute: .bottom, relatedBy: .equal, toItem: msgLabel, attribute: .top, multiplier: 1, constant: -18).isActive = true
NSLayoutConstraint.init(item: msgLabel!, attribute: .left, relatedBy: .equal, toItem: _alertView, attribute: .left, multiplier: 1, constant: 8).isActive = true
NSLayoutConstraint.init(item: msgLabel!, attribute: .right, relatedBy: .equal, toItem: _alertView, attribute: .right, multiplier: 1, constant: -8).isActive = true
NSLayoutConstraint.init(item: msgLabel!, attribute: .bottom, relatedBy: .equal, toItem: cancelButton, attribute: .top, multiplier: 1, constant: -18).isActive = true
NSLayoutConstraint.init(item: centerLine!, attribute: .centerX, relatedBy: .equal, toItem: _alertView, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: centerLine!, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 0.5).isActive = true
NSLayoutConstraint.init(item: centerLine!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 30).isActive = true
NSLayoutConstraint.init(item: centerLine!, attribute: .centerY, relatedBy: .equal, toItem: cancelButton, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: cancelButton!, attribute: .left, relatedBy: .equal, toItem: _alertView, attribute: .left, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: cancelButton!, attribute: .bottom, relatedBy: .equal, toItem: _alertView, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: cancelButton!, attribute: .right, relatedBy: .equal, toItem: centerLine, attribute: .right, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: cancelButton!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 48).isActive = true
NSLayoutConstraint.init(item: sureButton!, attribute: .right, relatedBy: .equal, toItem: _alertView, attribute: .right, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: sureButton!, attribute: .bottom, relatedBy: .equal, toItem: _alertView, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: sureButton!, attribute: .left, relatedBy: .equal, toItem: centerLine, attribute: .right, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint.init(item: sureButton!, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 48).isActive = true
}
}