簡體   English   中英

帶漸變的半圓形進度條 swift

[英]Half circular progress bar with gradient swift

我想使用swift在iOS中創建一個漸變顏色的half circular progress bar 。進度條的最小值為300,進度條的最大值為900。進度條的當前值是動態的。 我附上屏幕截圖 ans css 以供顏色參考。 有人可以給我一個小的工作演示嗎?

半循環進度

下面是 CSS -

/* Layout Properties */
top: 103px;
left: 105px;
width: 165px;
height: 108px;

/* UI Properties */

 background: transparent linear-gradient
(269deg, #32E1A0 0%, #EEED56 23%, #EFBF39 50%, #E59148 75%, #ED4D4D 100%)
 0% 0% no-repeat padding-box;
 opacity: 1;

特性

您可以使用名為MKMagneticProgress 的框架創建不同但相似的進度條

示例代碼:-

import MKMagneticProgress

@IBOutlet weak var magProgress:MKMagneticProgress!

override func viewDidLoad() {
    magProgress.setProgress(progress: 0.5, animated: true)
    magProgress.progressShapeColor = UIColor.blue
    magProgress.backgroundShapeColor = UIColor.yellow
    magProgress.titleColor = UIColor.red
    magProgress.percentColor = UIColor.black

    magProgress.lineWidth = 10
    magProgress.orientation = .top
    magProgress.lineCap = .round

    magProgress.title = "Title"
    magProgress.percentLabelFormat = "%.2f%%"

}

我希望它會起作用...... :)

這可以解決您在 swiftui 中的問題

在此處輸入圖像描述

import SwiftUI

struct ContentView: View {
    @State var progressValue: Float = 0.3
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State private var degress: Double = -110
    
    var body: some View {
        
        VStack {
            ZStack{
                
                ProgressBar(progress: self.$progressValue)
                    .frame(width: 250.0, height: 250.0)
                    .padding(40.0).onReceive(timer) { _ in
                        withAnimation {
                            if progressValue < 0.8999996 {
                                progressValue += 0.0275
                            }
                        }
                    }
                
                ProgressBarTriangle(progress: self.$progressValue).frame(width: 280.0, height: 290.0).rotationEffect(.degrees(degress), anchor: .bottom)
                    .offset(x: 0, y: -150).onReceive(timer) { input in
                        withAnimation(.linear(duration: 0.01).speed(200)) {
                            if degress < 110.0 {
                                degress += 10
                            }
                            print(degress)
                        }
                    }
            }
            Spacer()
        }
    }
    
    struct ProgressBar: View {
        @Binding var progress: Float
        
        var body: some View {
            ZStack {
                Circle()
                    .trim(from: 0.3, to: 0.9)
                    .stroke(style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round))
                    .opacity(0.3)
                    .foregroundColor(Color.gray)
                    .rotationEffect(.degrees(54.5))
                
                Circle()
                    .trim(from: 0.3, to: CGFloat(self.progress))
                    .stroke(style: StrokeStyle(lineWidth: 12.0, lineCap: .round, lineJoin: .round))
                    .fill(AngularGradient(gradient: Gradient(stops: [
                        .init(color: Color.init(hex: "ED4D4D"), location: 0.39000002),
                        .init(color: Color.init(hex: "E59148"), location: 0.48000002),
                        .init(color: Color.init(hex: "EFBF39"), location: 0.5999999),
                        .init(color: Color.init(hex: "EEED56"), location: 0.7199998),
                        .init(color: Color.init(hex: "32E1A0"), location: 0.8099997)]), center: .center))
                    .rotationEffect(.degrees(54.5))
                
                VStack{
                    Text("824").font(Font.system(size: 44)).bold().foregroundColor(Color.init(hex: "314058"))
                    Text("Great Score!").bold().foregroundColor(Color.init(hex: "32E1A0"))
                }
            }
        }
    }
    
    struct ProgressBarTriangle: View {
        @Binding var progress: Float
        
        
        var body: some View {
            ZStack {
                Image("triangle").resizable().frame(width: 10, height: 10, alignment: .center)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

extension Color {
    init(hex: String) {
        let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
        var int: UInt64 = 0
        Scanner(string: hex).scanHexInt64(&int)
        let a, r, g, b: UInt64
        switch hex.count {
        case 3: // RGB (12-bit)
            (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
        case 6: // RGB (24-bit)
            (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
        case 8: // ARGB (32-bit)
            (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
        default:
            (a, r, g, b) = (1, 1, 1, 0)
        }
        
        self.init(
            .sRGB,
            red: Double(r) / 255,
            green: Double(g) / 255,
            blue:  Double(b) / 255,
            opacity: Double(a) / 255
        )
    }
}

我實現了類似你的進度條的東西,用它來升級 - 獲得經驗值。 進步。,

如果你 go 從 300 到 1000,總條數是 1500 progressFrom: 300/1500, progressTo: 1000/1500..

func progressAnimation(duration: TimeInterval, progressFrom: CGFloat, progressTo: CGFloat) {
    if progressFrom == 0 {
        baseProgressLayer.removeFromSuperlayer()
    }
    
    let circlePath = UIBezierPath(ovalIn: CGRect(center: CGPoint(x: 93.0, y: 93.0), size: CGSize(width: 178, height: 178)))
    
    progressLayer.path = circlePath.cgPath
    progressLayer.fillColor = UIColor.clear.cgColor
    progressLayer.strokeColor = getColor(progress: progressTo).cgColor
    progressLayer.lineWidth = 8.0
    layer.addSublayer(progressLayer)
    layer.transform = CATransform3DMakeRotation(CGFloat(90 * Double.pi / 180), 0, 0, -1)
    
    let end = CABasicAnimation(keyPath: "strokeEnd")
    end.fromValue = progressFrom
    end.toValue = progressTo
    end.duration = duration * 0.85
    end.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
    end.fillMode = CAMediaTimingFillMode.forwards
    end.isRemovedOnCompletion = false
    
    let color = CABasicAnimation(keyPath: "strokeColor")
    color.fromValue = getColor(progress: progressFrom).cgColor
    color.toValue = getColor(progress: progressTo).cgColor
    color.duration = duration * 0.85
    color.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
    color.fillMode = CAMediaTimingFillMode.forwards
    color.isRemovedOnCompletion = false
    
    let group = CAAnimationGroup()
    group.animations = [end, color]
    group.duration = duration * 0.85
    progressLayer.strokeStart = progressFrom
    progressLayer.strokeEnd = progressTo
    progressLayer.add(group, forKey: "move")

    if progressFrom != 0 {
        let color2 = CABasicAnimation(keyPath: "strokeColor")
        color2.fromValue = getColor(progress: progressFrom).cgColor
        color2.toValue = getColor(progress: progressTo).cgColor
        color2.duration = duration * 0.85
        color2.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
        color2.fillMode = CAMediaTimingFillMode.forwards
        color2.isRemovedOnCompletion = false
        
       baseProgressLayer.add(color2, forKey: "baseColor")
    }
    
}

有一個擴展以獲得進步的顏色

擴展 CircularProgressBar {

private func getColor (progress: CGFloat) -> UIColor{
    if progress >= 0 && progress <= 0.5{
        return UIColor(red: CGFloat(255 / 255), green: CGFloat((0+((108-0)*progress*2)) / 255), blue: 0, alpha: 1.0)
    }
    else if progress > 0.5 && progress <= 1.0 {
        return UIColor(red: CGFloat((255-((255-126)*(progress-0.5)*2)) / 255), green: CGFloat((108+((211-108)*(progress-0.5)*2)) / 255), blue: CGFloat((0+((33-0)*(progress-0.5)*2)) / 255), alpha: 1.0)
    }
    else {
        return UIColor.green
    }
}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM