126 lines
3.5 KiB
Swift
126 lines
3.5 KiB
Swift
//
|
|
// SPPlayerProgressView.swift
|
|
// ShortPlay
|
|
//
|
|
// Created by 曾觉新 on 2025/4/9.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class SPPlayerProgressView: UIView {
|
|
|
|
///滑动开始
|
|
var panStart: (() -> Void)?
|
|
|
|
///滑动中
|
|
var panChange: ((_ progress: CGFloat) -> Void)?
|
|
|
|
///滑动完成回调
|
|
var panFinish: ((_ progress: CGFloat) -> Void)?
|
|
|
|
var progress: CGFloat = 0 {
|
|
didSet {
|
|
if !isPaning {
|
|
setNeedsDisplay()
|
|
}
|
|
}
|
|
}
|
|
|
|
///用来记录滑动时的当前进度
|
|
private var tempProgress: CGFloat = 0
|
|
|
|
///滑动进度
|
|
private var panProgress: CGFloat = 0
|
|
|
|
var progressColor: UIColor = .red
|
|
var currentProgress: UIColor = .white
|
|
|
|
var lineWidth: CGFloat = 2
|
|
|
|
///是否在滑动中
|
|
private var isPaning: Bool = false
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
self.backgroundColor = .clear
|
|
|
|
let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(sender:)))
|
|
self.addGestureRecognizer(pan)
|
|
|
|
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(sender:)))
|
|
self.addGestureRecognizer(tap)
|
|
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
|
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
|
super.traitCollectionDidChange(previousTraitCollection)
|
|
setNeedsDisplay()
|
|
}
|
|
|
|
override func draw(_ rect: CGRect) {
|
|
super.draw(rect)
|
|
guard let context = UIGraphicsGetCurrentContext() else { return }
|
|
let width = rect.width
|
|
let height = rect.height
|
|
|
|
var progress = self.progress
|
|
if self.isPaning {
|
|
progress = self.panProgress
|
|
}
|
|
|
|
///绘制进度
|
|
let progressPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width, height: lineWidth), cornerRadius: lineWidth / 2)
|
|
context.addPath(progressPath.cgPath)
|
|
context.setFillColor(progressColor.cgColor)
|
|
context.fillPath()
|
|
|
|
///绘制当前进度
|
|
let currentPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width * progress, height: lineWidth), cornerRadius: lineWidth / 2)
|
|
context.addPath(currentPath.cgPath)
|
|
context.setFillColor(currentProgress.cgColor)
|
|
context.fillPath()
|
|
}
|
|
|
|
}
|
|
|
|
extension SPPlayerProgressView {
|
|
|
|
@objc func handlePanGesture(sender: UIPanGestureRecognizer) {
|
|
|
|
switch sender.state {
|
|
case .began:
|
|
self.isPaning = true
|
|
self.tempProgress = self.progress
|
|
sender.setTranslation(CGPoint(x: 0, y: 0), in: self)
|
|
self.panStart?()
|
|
|
|
case .changed:
|
|
let point = sender.translation(in: self)
|
|
let offsetX = point.x / self.width
|
|
self.panProgress = self.tempProgress + offsetX
|
|
if self.panProgress < 0 {
|
|
self.panProgress = 0
|
|
}
|
|
self.panChange?(self.panProgress)
|
|
setNeedsDisplay()
|
|
|
|
default:
|
|
self.isPaning = false
|
|
self.panFinish?(self.panProgress)
|
|
|
|
self.panProgress = 0
|
|
}
|
|
}
|
|
|
|
@objc func handleTapGesture(sender: UITapGestureRecognizer) {
|
|
let point = sender.location(in: self)
|
|
let offsetX = point.x / self.width
|
|
self.panFinish?(offsetX)
|
|
}
|
|
}
|