如何自定义实现一个系统的UISwitch

  • 实现效果


    CustomSwitch-swift.gif
  • 实现思路

  1. UI包括底部背景View和开关View
  2. 在点击过程中对底部背景和开关坐颜色渐变动画和开关的位移动画
  • 具体实现
import UIKit

/// 开关点击事件
typealias SwitchValueChange = (Bool) -> ()

struct SwitchConfig {
    
    /// 关闭背景颜色
    let offBgColor = UIColor(red: 0 / 255.0, green: 0 / 255.0, blue: 0 / 255.0, alpha: 0.2)
    /// 打开背景颜色
    let onBgColor = UIColor(red: 70 / 255.0, green: 0 / 255.0, blue: 3 / 255.0, alpha: 1)
    
    /// 关闭圆点颜色
    let offPointColor = UIColor(red: 153 / 255.0, green: 153 / 255.0, blue: 153 / 255.0, alpha: 1)
    /// 打开圆点颜色
    let onPointColor = UIColor(red: 158 / 255.0, green: 0 / 255.0, blue: 6 / 255.0, alpha: 1)
    
    /// 背景View的上下边距
    let bgMargin: CGFloat = 7
    
    /// 圆点的上下边距
    let pointMargin: CGFloat = 5
}

class CustomSwitch: UIControl {

    /// 背景View
    var bgView: UIView!
    
    /// 开关圆点View
    var pointView: UIView!
    
    /// 配置
    var config: SwitchConfig!{
        didSet{
            self.updateUI()
        }
    }
    
    var  valueChangedHandle: SwitchValueChange?
    
    /// 开关状态
    var isOn: Bool!{
        didSet{
            if isOn {
                var frame: CGRect = self.pointView.frame
                frame.origin.x = self.bgView.frame.maxX - self.pointView.frame.width
                
                UIView.animate(withDuration: 0.25, animations: {
                    self.bgView.backgroundColor = self.config.onBgColor
                    self.pointView.backgroundColor = self.config.onPointColor
                    self.pointView.frame = frame
                })
            } else {
                
                var frame: CGRect = self.pointView.frame
                frame.origin.x = self.bgView.frame.minX
                
                UIView.animate(withDuration: 0.25, animations: {
                    self.bgView.backgroundColor = self.config.offBgColor
                    self.pointView.backgroundColor = self.config.offPointColor
                    self.pointView.frame = frame
                })
            }
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)

        // 底部背景
        self.bgView = UIView()
        self.addSubview(self.bgView)
        self.bgView.layer.masksToBounds = true
        self.bgView.isUserInteractionEnabled = false
    
        // 开关按钮
        self.pointView = UIView()
        self.addSubview(self.pointView)
        self.pointView.layer.masksToBounds = true
        self.pointView.isUserInteractionEnabled = false

        self.isOn = false
        
        self.config = SwitchConfig()

        self.addTarget(self, action: #selector(self.stateChanges), for: .touchUpInside)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 布局
        self.bgView.frame = CGRect(x: 0, y: self.config.bgMargin, width: frame.width, height: frame.height - self.config.bgMargin * 2)
        
        let pointWidth = frame.height - self.config.pointMargin * 2
        self.pointView.frame = CGRect(x: self.bgView.frame.minX, y: self.config.pointMargin, width: pointWidth, height: pointWidth)
        
        self.updateUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 响应事件
    @objc func stateChanges() {
        
        self.isOn = !self.isOn
        if self.valueChangedHandle != nil {
            self.valueChangedHandle!(self.isOn)
        }
    }
    
    /// 设置圆角和背景色
    func updateUI() {
        
        self.bgView.layer.cornerRadius = (self.frame.height - self.config.bgMargin * 2) * 0.5
        self.bgView.backgroundColor = self.config.offBgColor
        self.pointView.layer.cornerRadius = (self.frame.height - self.config.pointMargin * 2) * 0.5
        self.pointView.backgroundColor = self.config.offPointColor
    }
}
  • 怎么调用?
  1. 默认创建
        self.customSwitch = CustomSwitch()
        self.view.addSubview(customSwitch)
        customSwitch.center = self.view.center
        customSwitch.bounds = CGRect(x: 0, y: 0, width: 40, height: 30)
        customSwitch.valueChangedHandle = {(isOn) in
            print(isOn)
        }
  1. 改变UI


    A144C001-7335-4C00-A635-247A4FCE6804.png

详情请点击:Demo地址

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 第三章 徐维夏定定的看着来往的车辆,红灯停绿灯行。任凭指甲嵌进手掌肉里,呼吸低沉, “顾希南,想念太奢侈,你用不起...
    苏噼里阅读 444评论 2赞 0
  • 一.土鸡 群鸡里有一只大公鸡 它模样俊俏 甚得其他母鸡的喜爱 于是 整日里调戏调戏其它同伴 无所事事 终于有一天...
    亲亲青草阅读 869评论 9赞 4

友情链接更多精彩内容