swift 自定义一个AlertController(AutoLayout)

系统的UIAlertController,在弹出时并没有动画效果,只是平静的展示在屏幕上,而且白底蓝字确实一斤能审美疲劳了,所以我想要自定义一个Alert。

参考了很多的开源,基本都是基于Frame来做布局,这样来做未免计算量会过于的大,显得繁杂,所以,我要试一下用AutoLayout来做。因为我可以通过AutoLayout的布局代码大概构想出页面的样式(前提是没有报错。。。),其实就是懒得算。先来看一下效果图

Alert.gif

点击了"点我"按钮后,会在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
    }
    
}

你可能感兴趣的:(swift 自定义一个AlertController(AutoLayout))