自定义UIProgressView,实现渐变色进度条,带动画的

//
//  RCGradientProgressView.swift
//  RemoteControlUnit
//
//  Created by lsp on 2021/7/21.
//

import UIKit

open class RCGradientProgressView: UIView {
    
    //进度条完成部分的渐变颜色,设置单个为纯色,设置多个为渐变色
    public var progressColors: [UIColor] = [.blue] {
        didSet {
            if progressColors.count == 0 {
                gradientLayer.colors = nil
            } else if progressColors.count == 1 {
                let color = progressColors[0]
                gradientLayer.colors = [color, color].map { $0.cgColor }
            } else {
                gradientLayer.colors = progressColors.map { $0.cgColor }
            }
        }
    }
    
    //进度条完成部分的圆角半径
    public var progressCornerRadius: CGFloat = 0 {
        didSet {
            maskLayer.cornerRadius = progressCornerRadius
        }
    }
    
    //渐变Layer
    public let gradientLayer: CAGradientLayer = {
        let layer = CAGradientLayer()
        layer.anchorPoint = .zero
        layer.startPoint = .zero
        layer.endPoint = CGPoint(x: 1.0, y: 0.0)
        return layer
    }()
    
    //动画持续时间
    public var animationDuration: TimeInterval = 0.3
    
    //动画时间函数
    public var timingFunction: CAMediaTimingFunction = CAMediaTimingFunction(name: .default)
    
    private var privateProgress: Float = 0
    private let maskLayer: CALayer = {
        let layer = CALayer()
        layer.backgroundColor = UIColor.white.cgColor

        return layer
    }()
    
    //当前进度
    public var progress: Float {
        get {
            return privateProgress
        }
        set {
            setProgress(newValue, animated: false)
        }
    }
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required public init?(coder: NSCoder) {
        super.init(coder: coder)
        setupUI()
    }
    
    func setupUI() {
        let color = progressColors[0]
        gradientLayer.colors = [color, color].map { $0.cgColor }
        gradientLayer.mask = maskLayer
        layer.insertSublayer(gradientLayer, at: 0)
    }
    
    open override func layoutSubviews() {
        super.layoutSubviews()
        // 没有内间距
        gradientLayer.frame = bounds.inset(by: .zero)
        var bounds = gradientLayer.bounds
        bounds.size.width *= CGFloat(progress)
        maskLayer.frame = bounds
    }
    
    public func setProgress(_ progress: Float, animated: Bool) {
        let validProgress = min(1.0, max(0.0, progress))
        if privateProgress == validProgress {
            return
        }
        privateProgress = validProgress
        
        //动画时长
        var duration = animated ? animationDuration : 0
        if duration < 0 {
            duration = 0
        }
        
        CATransaction.begin()
        CATransaction.setAnimationDuration(duration)
        CATransaction.setAnimationTimingFunction(timingFunction)
        
        //更新maskLayer的frame
        var bounds = self.gradientLayer.bounds
        bounds.size.width *= CGFloat(validProgress)
        self.maskLayer.frame = bounds
        
        CATransaction.commit()
    }
}

 使用: 

lazy var progressView: RCGradientProgressView = {

        $0.layer.cornerRadius = 5

        $0.progressCornerRadius = 5

        $0.backgroundColor = .gray

        $0.progressColors = [.orange, .blue]

//        $0.animationDuration = 2.0

        return $0

    }(RCGradientProgressView(frame: CGRect(x: 20, y: 100, width: self.view.bounds.size.width - 40, height: 10)))

    

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        progressView.setProgress(0.6, animated: true)

    }

posted on 2021-07-22 20:11  大圣ios博客  阅读(1397)  评论(0编辑  收藏  举报