自定义 videoplayerp
30 November 2023
自定义 VideoPlayerProgressSlider
class VideoPlayerProgressSlider: UISlider {
var trackHeight: CGFloat = 8 // 轨道的高度
var dotPositions: [CGFloat] = [] // 需要标注的位置值
lazy var thumbCoverView: UIView = { // 用于表示滑块上方的视图
let view = UIView()
view.layer.cornerRadius = 10.0
view.backgroundColor = .brown // 设置圆形视图的背景色
view.isUserInteractionEnabled = false
return view
}()
lazy var dotLayerContainer: CALayer = {
let layer = CALayer()
return layer
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(thumbCoverView)
layer.insertSublayer(dotLayerContainer, below: thumbCoverView.layer)
dotLayerContainer.backgroundColor = UIColor.clear.cgColor
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let pointForThumbCoverView = thumbCoverView.convert(point, from: self)
if thumbCoverView.bounds.contains(pointForThumbCoverView) {
return self
}
return super.hitTest(point, with: event)
}
override func trackRect(forBounds bounds: CGRect) -> CGRect {
var newBounds = super.trackRect(forBounds: bounds)
newBounds.size.height = trackHeight // 设置轨道的高度
return newBounds
}
override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
let superThumbRect = super.thumbRect(forBounds: bounds, trackRect: rect, value: value)
thumbCoverView.bounds = CGRect(x: 0, y: 0, width: superThumbRect.width, height: superThumbRect.height)
thumbCoverView.center = CGPoint(x: superThumbRect.midX, y: superThumbRect.midY)
thumbCoverView.layer.cornerRadius = superThumbRect.width / 2.0
return superThumbRect
}
override func layoutSubviews() {
super.layoutSubviews()
updateThumbCoverPosition()
}
private func updateThumbCoverPosition() {
let thumbRect = thumbRect(forBounds: bounds, trackRect: trackRect(forBounds: bounds), value: value)
thumbCoverView.center = CGPoint(x: thumbRect.midX, y: thumbRect.midY)
}
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
let beganTracking = super.beginTracking(touch, with: event)
if beganTracking {
updateThumbCoverPosition()
}
return beganTracking
}
override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
let continuedTracking = super.continueTracking(touch, with: event)
if continuedTracking {
updateThumbCoverPosition()
}
return continuedTracking
}
override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
super.endTracking(touch, with: event)
}
override func draw(_ rect: CGRect) {
super.draw(rect)
// 移除dotLayerContainer上的所有子图层
dotLayerContainer.sublayers?.forEach { $0.removeFromSuperlayer() }
for position in dotPositions {
drawDot(at: position)
}
}
private func drawDot(at position: CGFloat) {
let dotRadius: CGFloat = 2 // 红点的半径
let dotCenterX = position / CGFloat(maximumValue) * bounds.width
let dotCenterY = trackRect(forBounds: bounds).origin.y + trackHeight / 2 // 计算红点的 Y 坐标
let dotLayer = CALayer()
dotLayer.backgroundColor = UIColor.blue.cgColor
dotLayer.bounds = CGRect(x: 0, y: 0, width: dotRadius * 2, height: dotRadius * 2)
dotLayer.position = CGPoint(x: dotCenterX, y: dotCenterY)
dotLayer.cornerRadius = dotRadius
dotLayerContainer.addSublayer(dotLayer)
}
}
class ViewController: UIViewController {
var videoPlayerSlider: VideoPlayerProgressSlider!
override func viewDidLoad() {
super.viewDidLoad()
// 创建 VideoPlayerProgressSlider 实例
videoPlayerSlider = VideoPlayerProgressSlider(frame: CGRect(x: 20, y: 100, width: 300, height: 16))
// 设置进度条样式
videoPlayerSlider.minimumTrackTintColor = .red
videoPlayerSlider.maximumTrackTintColor = .gray
// 设置滑块图片为灰白色的圆形
let thumbImage = UIImage(systemName: "circle.fill")?.withTintColor(.lightGray, renderingMode: .alwaysOriginal)
videoPlayerSlider.setThumbImage(thumbImage, for: .normal)
// 设置最小值和最大值
videoPlayerSlider.minimumValue = 0
videoPlayerSlider.maximumValue = 100
// 设置初始播放进度
videoPlayerSlider.value = 50
// 设置红点位置
videoPlayerSlider.dotPositions = [10, 20, 40, 50, 80]
// 添加进度条到视图中
view.addSubview(videoPlayerSlider)
}
// 模拟播放进度更新
func updateProgress() {
// 模拟播放进度增加
videoPlayerSlider.value += 1
}
// 模拟点击按钮更新播放进度
@IBAction func updateProgressButtonTapped(_ sender: UIButton) {
updateProgress()
}
}
