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
网友评论