请稍侯

自定义 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()
    }

}