效果图
@objc protocol CABatterySliderViewDelegate: NSObjectProtocol {
/// 滑条拖动回调
/// - Parameters:
/// - sliderView: 滑条
/// - value: 位置数值
@objc optional func sliderView(_ sliderView: CABatterySliderView, valueChanged value: Int)
}
class CABatterySliderView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupSubviews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public var value: Float? {
didSet {
guard let value = value else { return }
let sliderValue = value / maxValue.float
sliderView.setValue(sliderValue, animated: true)
DispatchQueue.main.asyncAfter(delay: 0.3) { [weak self] in
self?.updateValue(sliderValue)
}
}
}
weak var delegate: CABatterySliderViewDelegate?
private func setupSubviews() {
addSubviews([wrapperView, minLabel, sliderView, maxLabel])
wrapperView.addSubviews([wrapperImage, valueLabel])
wrapperView.snp.makeConstraints { make in
make.top.equalToSuperview()
make.width.equalTo(48)
make.height.equalTo(32)
make.left.equalTo(minLabel.snp.right).offset(magrin)
}
minLabel.snp.makeConstraints { make in
make.leading.equalTo(16)
make.top.equalTo(wrapperView.snp.bottom).offset(-10)
make.width.equalTo(10)
make.height.equalTo(30)
}
maxLabel.snp.makeConstraints { make in
make.trailing.equalTo(-16)
make.top.equalTo(wrapperView.snp.bottom).offset(-10)
make.width.equalTo(40)
make.height.equalTo(30)
}
sliderView.snp.makeConstraints { make in
make.left.equalTo(minLabel.snp.right).offset(16)
make.right.equalTo(maxLabel.snp.left).offset(-16)
make.top.equalTo(wrapperView.snp.bottom).offset(-10)
make.height.equalTo(30)
}
wrapperImage.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
valueLabel.snp.makeConstraints { make in
make.leading.trailing.equalToSuperview()
make.top.equalTo(0)
make.height.equalTo(22)
}
}
@objc
private func sliderValueChange(_ slider: UISlider) {
let value = Int(round(slider.value * maxValue.float))
delegate?.sliderView?(self, valueChanged: value)
updateValue(slider.value)
}
private func updateValue(_ sliderValue: Float) {
let value = Int(round(sliderValue * maxValue.float))
let orginX = sliderView.width * CGFloat(sliderValue) + 16 - 24
wrapperView.snp.updateConstraints { make in
make.left.equalTo(minLabel.snp.right).offset(orginX)
}
valueLabel.text = "\(value)%"
}
private let magrin = 0
private lazy var minLabel: UILabel = {
let label = UILabel()
label.theme_font = Themes.Global.regularFont(size: 14)
label.theme_textColor = Themes.Text.thirdColor
label.text = minValue.string
return label
}()
private lazy var maxLabel: UILabel = {
let label = UILabel()
label.theme_font = Themes.Global.regularFont(size: 14)
label.theme_textColor = Themes.Text.thirdColor
label.text = "\(maxValue)%"
return label
}()
private lazy var valueLabel: UILabel = {
let label = UILabel()
label.theme_font = Themes.Global.regularFont(size: 14)
label.textColor = UIColor.colorWithHexString("#252626", 1)
label.textAlignment = .center
label.text = "\(minValue)km"
return label
}()
private lazy var wrapperView: UIView = {
let view = UIView()
return view
}()
private lazy var wrapperImage: UIImageView = {
let image = UIImage(named: "battery_icon_label", in: CAHelper.resourceBundle, compatibleWith: nil) ?? UIImage()
let view = UIImageView()
view.theme_image = ThemeImagePicker(images: image, image)
return view
}()
private lazy var sliderView: CABatterySlider = {
let image = UIImage(named: "battery_icon_slider", in: CAHelper.resourceBundle, compatibleWith: nil) ?? UIImage()
let view = CABatterySlider()
view.minimumValue = 0.0
view.maximumValue = 1.0
view.theme_minimumTrackTintColor = Themes.Background.mainColor
view.theme_maximumTrackTintColor = Themes.Background.subColor
view.setThumbImage(image, for: .normal)
view.addTarget(self, action:#selector(sliderValueChange(_:)), for: .valueChanged)
return view
}()
private let minValue = 0
private let maxValue = 100
}
class CABatterySlider: UISlider {
override func trackRect(forBounds bounds: CGRect) -> CGRect {
let orginY = (bounds.size.height - 6) / 2
return CGRect(x: bounds.origin.x, y: orginY, width: bounds.size.width, height: 6)
}
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
var tempRect = rect
tempRect.origin.x = rect.origin.x - 10
tempRect.size.width = rect.size.width + 20
return CGRectInset(super.thumbRect(forBounds: bounds, trackRect: tempRect, value: value), 10, 10)
}
}