美文网首页
iOS 自定义滑动条

iOS 自定义滑动条

作者: gaookey | 来源:发表于2020-06-19 18:31 被阅读0次
    import UIKit
    
    class SliderView: UIView {
        
        private let sliderCircleSize: CGFloat = 20
        private let sliderValueSize: CGFloat = 30
        private let topSliderHeight: CGFloat = 9
        private let bottomSliderHeight: CGFloat = 5
        
        var touchesMovedHandler: ((_ progress: CGFloat, _ state: UIGestureRecognizer.State) -> ())?
        
        var progress: CGFloat = 0 {
            willSet {
                topSlider.snp.updateConstraints { (make) in
                    make.width.equalTo(newValue * (bounds.size.width - sliderCircleSize / 2))
                }
            }
        }
        
        lazy var sliderValue: UILabel = {
            let lable = UILabel()
            lable.textColor = .black
            lable.font = .systemFont(ofSize: 12)
            lable.textAlignment = .center
            lable.isHidden = true
            return lable
        }()
        
        private lazy var sliderCircle: UIView = {
            let view = UIView()
            view.backgroundColor = .cyan
            view.layer.cornerRadius = sliderCircleSize / 2
            view.layer.masksToBounds = true
            view.layer.borderColor = UIColor.black.cgColor
            view.layer.borderWidth = 2
            return view
        }()
        
        private lazy var topSlider: UIView = {
            let view = UIView()
            view.backgroundColor = .cyan
            view.layer.cornerRadius = topSliderHeight / 2
            view.layer.masksToBounds = true
            view.layer.borderColor = UIColor.black.cgColor
            view.layer.borderWidth = 2
            return view
        }()
        
        private lazy var bottomSlider: UIView = {
            let view = UIView()
            view.backgroundColor = .lightGray
            view.layer.cornerRadius = bottomSliderHeight / 2
            view.layer.masksToBounds = true
            return view
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            addControls()
            
            let pan = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
            addGestureRecognizer(pan)
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    extension SliderView {
        
        @objc func panGestureAction(_ pan: UIPanGestureRecognizer) {
            
            let translation = pan.translation(in: self)
            var width = (bounds.size.width - sliderCircleSize / 2) * progress + translation.x
            
            if pan.state == .changed {
                if width > bounds.size.width - sliderCircleSize {
                    width = bounds.size.width - sliderCircleSize
                }
                if width < 0 {
                    width = 0
                }
                topSlider.snp.updateConstraints { (make) in
                    make.width.equalTo(width)
                }
                
                sliderValue.isHidden = false
            }
            
            if pan.state == .ended {
                sliderValue.isHidden = true
                progress = topSlider.frame.size.width / (bounds.size.width - sliderCircleSize / 2)
            }
            
            let value: CGFloat = width / (bounds.size.width - sliderCircleSize)
            sliderValue.text = String(format: "%0.0f", value * 100)
            if let block = touchesMovedHandler {
                block(value, .changed)
            }
        }
        
        func addControls() {
            
            addSubview(bottomSlider)
            bottomSlider.snp.makeConstraints { (make) in
                make.left.equalTo(sliderCircleSize / 2)
                make.right.equalTo(-(sliderCircleSize / 2))
                make.height.equalTo(bottomSliderHeight)
                make.centerY.equalToSuperview()
            }
            
            addSubview(topSlider)
            topSlider.snp.makeConstraints { (make) in
                make.left.centerY.equalTo(bottomSlider)
                make.height.equalTo(topSliderHeight)
                make.width.equalTo(0)
            }
            
            addSubview(sliderCircle)
            sliderCircle.snp.makeConstraints { (make) in
                make.width.height.equalTo(sliderCircleSize)
                make.centerY.equalToSuperview()
                make.centerX.equalTo(topSlider.snp.right)
            }
            
            addSubview(sliderValue)
            sliderValue.snp.makeConstraints { (make) in
                make.centerX.equalTo(sliderCircle)
                make.width.height.equalTo(sliderValueSize)
                make.bottom.equalTo(sliderCircle.snp.top)
            }
        }
        override func draw(_ rect: CGRect) {
            topSlider.snp.updateConstraints { (make) in
                make.width.equalTo(progress * (bounds.size.width - sliderCircleSize / 2))
            }
        }
    }
    
    image.png
    import UIKit
    
    class ProgressView: UIView {
        
        private let borderWidth: CGFloat = 2
        private var progressView = UIView()
        
        var progress: CGFloat = 0 {
            willSet {
                if newValue > 0 && newValue < 1 {
                    let maxWidth = self.bounds.size.width - borderWidth * 2 * 2
                    let heigth = self.bounds.size.height - borderWidth * 2 * 2
                    progressView.frame = CGRect(x: borderWidth * 2, y: borderWidth * 2, width: maxWidth * newValue, height: heigth)
                }
            }
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            
            layer.cornerRadius = bounds.size.height * 0.5
            layer.masksToBounds = true
            layer.borderColor = UIColor.white.cgColor
            layer.borderWidth = borderWidth
            backgroundColor = .lightGray
        }
        
        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        override func draw(_ rect: CGRect) {
            
            progressView.backgroundColor = .white
            progressView.layer.cornerRadius = (bounds.size.height - borderWidth * 2 * 2) * 0.5
            progressView.layer.masksToBounds = true
            addSubview(progressView)
        }
    }
    
    image.png

    相关文章

      网友评论

          本文标题:iOS 自定义滑动条

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