Swift 实现系统弹窗动画协议

作者: 一粒咸瓜子 | 来源:发表于2021-12-07 10:54 被阅读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()
                }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:Swift 实现系统弹窗动画协议

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