需求
实现一个垂直的拖动及点击的自定义进度类型视图
一、第三方库
pod ‘SnapKit’
pod ‘HexColors’
二、代码
VerticalProgressView.swift
import UIKit
import SnapKit
let ScreenWidth: CGFloat = UIScreen.main.bounds.width
let ScreenHeight: CGFloat = UIScreen.main.bounds.height
let IsPhone: Bool = {
UIDevice.current.userInterfaceIdiom == .phone
}()
let IsPad: Bool = {
UIDevice.current.userInterfaceIdiom == .pad
}()
func FitWidth(_ width: CGFloat) -> CGFloat {
IsPhone ? ScreenWidth * width / 520.0 : width
}
protocol VerticalProgressViewDelegate: NSObjectProtocol {
func verticalProgressValueChanged(value: UInt8)
}
class VerticalProgressView : UIView {
private var okView: UIView!
weak var delegate: VerticalProgressViewDelegate?
var okColor: UIColor = .blue {
willSet {
okView.backgroundColor = newValue
}
}
var minValue: Float = 0
var maxValue: Float = 100
private var panGesture: UIPanGestureRecognizer!
var progressValue: Float = 0 {
willSet {
curValueUInt8 = UInt8(newValue)
}
}
private var curValueUInt8: UInt8 = 0
deinit {
removeGestureRecognizer(panGesture)
gestureRecognizers?.removeAll()
// print("释放")
}
override init(frame: CGRect) {
super.init(frame: frame)
okView = UIView()
addSubview(okView)
okView.snp.makeConstraints { make in
make.leading.trailing.top.equalToSuperview()
make.height.equalToSuperview()
}
panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureEvent(_:)))
addGestureRecognizer(panGesture)
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapGestureRecognizer(_:))))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override func draw(_ rect: CGRect) {
super.draw(rect)
let y = self.frame.size.height - rect.size.height * CGFloat(abs(progressValue - minValue) / abs(maxValue - minValue))
okView.frame = CGRect(x: 0, y: y, width: rect.size.width, height: rect.size.height)
}
@objc private func tapGestureRecognizer(_ tap: UITapGestureRecognizer) {
let location = tap.location(in: self)
let nV = min(max(location.y, 0), self.frame.height)
okView.frame.origin.y = nV
let privV = curValueUInt8
progressValue = roundf(Float((self.frame.height - nV) / self.frame.height) * abs(maxValue - minValue))
let l = UInt8(progressValue)
if l != privV {
delegate?.verticalProgressValueChanged(value: l)
}
}
@objc private func panGestureEvent(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .changed:
do {
gestureChanged(gesture: sender)
}
case .cancelled, .ended:
do {
gestureEnded(gesture: sender)
}
default:
break
}
}
private func gestureChanged(gesture: UIPanGestureRecognizer) {
let location: CGPoint = gesture.location(in: self)
let nV = min(max(location.y, 0), self.frame.height)
okView.frame.origin.y = nV
}
private func gestureEnded(gesture: UIPanGestureRecognizer) {
let location: CGPoint = gesture.location(in: self)
let nV = min(max(location.y, 0), self.frame.height)
okView.frame.origin.y = nV
let privV = curValueUInt8
progressValue = roundf(Float((self.frame.height - nV) / self.frame.height) * abs(maxValue - minValue))
let l = UInt8(progressValue)
if l != privV {
delegate?.verticalProgressValueChanged(value: l)
}
}
}
TestViewController.swift
extension TestViewController: VerticalProgressViewDelegate {
func verticalProgressValueChanged(value: UInt8) {
volumeProgressView.progressValue = Float(value)
}
}
class TestViewController: UIViewController {
private var volumeProgressView: VerticalProgressView!
override func viewDidLoad() {
super.viewDidLoad()
initUI()
}
private func initUI() {
volumeProgressView = VerticalProgressView()
volumeProgressView.delegate = self
volumeProgressView.okColor = UIColor("#008686")!
volumeProgressView.backgroundColor = UIColor("#6B7C84")
volumeProgressView.clipsToBounds = true
volumeProgressView.layer.cornerRadius = FitWidth(15)
volumeProgressView.progressValue = 50
view.addSubview(volumeProgressView)
volumeProgressView.snp.makeConstraints { make in
make.width.equalTo(FitWidth(30))
make.height.equalTo(FitWidth(200))
make.center.equalToSuperview()
}
}
}
总结
实现一个自定义的垂直拖动及点击功能的可显示进度类型的视图。