从0到1学习Swift工具文计算机语言

Swift 实现系统弹窗动画协议

2021-12-07  本文已影响0人  一粒咸瓜子

实现类似系统弹窗的动画效果:

import Foundation
import SnapKit

private var _coverKey = "alertCoverKey"
private var _constraintsClosureKey = "constraintsClosureKey"

protocol AlertSystemAnimationProtocol {
    /// 弹出
    func present()
    /// 消失
    func dismiss()
    /// alert 与 cover 的约束
    /// (注意调用顺序,应在 present 之前)
    func constrains(_ closure: @escaping (ConstraintMaker) -> Void)
}

extension AlertSystemAnimationProtocol where Self: UIView {
    
     private var _alertCover: UIView {
        set {
            objc_setAssociatedObject(self, &_coverKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            return ((objc_getAssociatedObject(self, &_coverKey) as? UIView) ?? UIView())
        }
    }
    
    
    private var _constrainsClosure: ((ConstraintMaker) -> Void)? {
        set {
            objc_setAssociatedObject(self, &_constraintsClosureKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        get {
            guard let closure = objc_getAssociatedObject(self, &_constraintsClosureKey) as? ((ConstraintMaker) -> Void) else {
                return nil
            }
            return closure
        }
    }
    
    func constrains(_ closure: @escaping (ConstraintMaker) -> Void) {
        _constrainsClosure = closure
    }
    
    func present() {
        let cover = UIView()
        cover.frame = UIScreen.main.bounds
        cover.backgroundColor = UIColor.color(color: .black, alpha: 0.25)
        cover.addSubview(self)
        
        if let constraintsClosure = _constrainsClosure {
            self.snp.makeConstraints(constraintsClosure)
        } else {
            self.snp.makeConstraints { make in
                make.center.equalToSuperview()
                make.left.equalTo(25.ratio)
            }
        }

        cover.alpha = 0
        self.alpha = 0.5
        
        UIApplication.shared.keyWindow?.addSubview(cover)
        cover.layoutIfNeeded()
        
        self.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
        
        UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseInOut) {
            cover.alpha = 1
            self.alpha = 1
            self.transform = CGAffineTransform.identity
        }
        _alertCover = cover
    }
    
    func dismiss() {
        UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseInOut) {
            self._alertCover.alpha = 0
        } completion: { isCompleted in
            if isCompleted {
                self.removeFromSuperview()
                self._alertCover.removeFromSuperview()
            }
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读