Swift面向协议编程(一)

2022-05-22  本文已影响0人  萤火驻守心间

面向协议编程(Pop):
特点:
1、不相关的两个类型优先考虑协议
2、可以给协议添加扩展
3、协议可以继承其他协议

模拟场景:实现点击button使view与button同时抖动并改变圆角,点击view还原圆角。定义协议viewProtocol继承于两个自定义协议。其中temProtocol1负责修改/还原圆角; temProtocol2负责添加抖动效果。

效果如图所示:


image.png

说明:
1、一个协议也可实现效果,如果功能复杂时可用多个协议区分。此处多协议仅为参考
2、协议扩展让面向协议编程成为可能
自定义协议:

protocol viewProtocol:temProtocol1, temProtocol2{
}
protocol temProtocol1 {
    
}
extension temProtocol1 where Self: UIView{

    func changeRadio() {
        layer.cornerRadius = 10
        layer.masksToBounds = true
    }
    func returnBack() {
        layer.cornerRadius = 0
    }
}
protocol temProtocol2 {
    
}
extension temProtocol2 where Self : UIView {
    func shake() {
        let animation = CABasicAnimation(keyPath: "position")
        animation.duration = 0.05
        animation.repeatCount = 5
        animation.autoreverses = true
        animation.fromValue = NSValue(cgPoint: CGPoint(x: self.center.x-4.0, y: self.center.y))
        animation.toValue = NSValue(cgPoint: CGPoint(x: self.center.x+4.0, y: self.center.y))
        layer.add(animation, forKey: "position")
    }
}

自定义view和button:

class LeftView: UIView,viewProtocol {
    
    private var tem = LeftRightViewModel()
    var vm: LeftRightViewModel {
        set {
            tem = newValue
        }
        get {
            tem
        }
    }
    override init(frame: CGRect) {
        super.init(frame: frame)
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(clickLeft))
        addGestureRecognizer(tap)
    }
    @objc func clickLeft() {
        vm.leftViewClick()
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

class RightButton: UIButton,viewProtocol {
    private var tem = LeftRightViewModel()
    var vm: LeftRightViewModel {
        set {
            tem  = newValue
        }
        get {
            tem
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setTitle("btn", for: .normal)
        addTarget(self, action: #selector(btnClick), for: .touchUpInside)
    }
    
    @objc func btnClick() {
        vm.rightBtnClick()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

viewmodel:

class LeftRightViewModel: NSObject {
    
    var clickReturn : (()->())?
    var lclickReturn : (()->())?
    func leftViewClick() {
        //还原
        lclickReturn?()
    }
    func rightBtnClick() {
        //抖动
        clickReturn?()
    }
    
}

viewController:

class ViewController: UIViewController {
    let vm: LeftRightViewModel = LeftRightViewModel()
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let left = LeftView(frame: CGRect(x: 140, y: 100, width: 100, height: 100))
        left.vm = vm
        left.backgroundColor = UIColor.lightGray
        view.addSubview(left)
        let right = RightButton(frame: CGRect(x: left.frame.maxX+30, y: 130, width: 40, height: 40))
        right.vm = vm
        right.backgroundColor = UIColor.orange
        view.addSubview(right)
        vm.clickReturn = {
            left.shake()
            right.shake()
            left.changeRadio()
            right.changeRadio()
        }
        vm.lclickReturn = {
            left.returnBack()
            right.returnBack()
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读