自定義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)

    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM