自定义开关按钮

331 阅读1分钟
class CustomSwitch: UIControl {
    
    public var isOn:Bool = true
    
    fileprivate let duration = 0.3 // 动画时间
    
    fileprivate var tintOnColor:UIColor = .orange // 开启状态的背景颜色
    fileprivate var tintOffColor:UIColor = .gray // 关闭状态的背景颜色
    fileprivate var textOnColor:UIColor = .white // 开启状态文字颜色
    fileprivate var textOffColor:UIColor = .darkGray // 关闭状态文字颜色
    
    fileprivate lazy var titleLabel:UILabel = {
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 12.0, weight: .bold)
        label.textAlignment = .center
        return label
    }()
    
    fileprivate var thumbView:UIView = {
        let view = UIView()
        view.backgroundColor = .white
        return view
    }()
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.addSubview(thumbView)
        self.addSubview(titleLabel)
        self.iniUI()
    }
    
    fileprivate func iniUI() {
    
        let backgroundColor = isOn ? tintOnColor : tintOffColor
        self.backgroundColor = backgroundColor
        self.layer.cornerRadius = self.frame.size.height / 2
        
        let y = 2.0
        let width = self.frame.size.height - 4.0
        let x = isOn ? (self.frame.size.width - width - 2.0) : 2.0
        thumbView.frame = CGRect(x: x, y: y, width: width, height: width)
        thumbView.layer.cornerRadius = width / 2
        
        labelFrame()
    }
    
    fileprivate func labelFrame() {
        let y = 2.0
        let width = 25.0
        let height = self.frame.size.height - 4.0
        let x = isOn ? (6.0) : (self.frame.size.width - width - 6.0)
        titleLabel.frame = CGRect(x: x, y: y, width: width, height: height)
        titleLabel.text = isOn ? "可用" : "禁用"
        titleLabel.textColor = isOn ? textOnColor : textOffColor
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        
        debugPrint("点击")
        self.actionAnimate {[weak self] in
            self?.sendActions(for: .valueChanged)
        }
    }
    
    // 点击动画
    fileprivate func actionAnimate(completion:@escaping(()->())) {
        isOn = !isOn
        let status = isOn
        let y = 2.0
        let width = self.frame.size.height - 4.0
        let x = status ? (self.frame.size.width - width - 2.0) : 2.0
        
        self.titleLabel.isHidden = true

        UIView.animate(withDuration: duration, delay: 0.0, options: [.curveEaseInOut,.transitionCrossDissolve]) {[weak self] in
            
            self?.thumbView.frame = CGRect(x: x, y: y, width: width, height: width)
            
        } completion: { [weak self] (result) in
            self?.backgroundColor = status ? self?.tintOnColor : self?.tintOffColor
            self?.titleLabel.isHidden = false
            self?.labelFrame()
            completion()
        }
    }
    
    public func setOn(on:Bool) {
        isOn = on
        iniUI()
    }
    
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */

}
let customSwitch = CustomSwitch(frame: CGRect(x: 0.0, y: 0.0, width: 53.0, height: 23.0))
customSwitch.isOn = false
customSwitch.addTarget(self, action: #selector(valueChange(_:)), for: .valueChanged)
self.view.addSubview(customSwitch)
customSwitch.snp.makeConstraints { make in
    make.left.top.equalToSuperview().offset(100.0)
    make.width.equalTo(53.0)
    make.height.equalTo(23.0)
}