SwiftUI,带有进度图像的圆形进度条

时间:2021-06-15 10:10:06

标签: swiftui progress-bar progress kdcircularprogress

我正在尝试在 SwiftUI 中实现一个圆形进度条,并带有关于进度和动画的图像。任何帮助或想法将不胜感激。

以下是我计划实施的内容:imageLink

这是我目前可以实现的:image2

这是我的代码:

struct CircularView: View {
    @State var progress:Double = 0
    var total:Double =  100
    let circleHeight:CGFloat = 217
    @State var xPos:CGFloat = 0.0
        
    @State var yPos:CGFloat = 0.0
    var body: some View {
        let pinHeight = circleHeight * 0.1
        
        VStack {
            
            Circle()
                .trim(from: 0.0, to: 0.6)
                .stroke(Color(.systemGray5),style: StrokeStyle(lineWidth: 8.0, lineCap: .round, dash: [0.1]))
                .frame(width: 278, height: 217, alignment: .center)
                .rotationEffect(.init(degrees: 162))
                .overlay(
                    Circle()
                        .trim(from: 0.0, to: CGFloat(progress) / CGFloat(total))
                        .stroke(Color.purple,style: StrokeStyle(lineWidth: 8.0, lineCap: .round, dash: [0.1]))
                        
                        .rotationEffect(.init(degrees: 162))
                        .rotation3DEffect(
                            .init(degrees: 1),
                            axis: (x: 1.0, y: 0.0, z: 0.0)
                        )
                        .animation(.easeOut)
                        .overlay(
                            Circle()
                                
                                .frame(width: pinHeight, height: pinHeight)
                                .foregroundColor(.blue)

                                .offset(x: 107 - xPos, y: 0 + yPos)
                                .animation(.easeInOut)
                                
                                .rotationEffect(.init(degrees: 162))
                                
                        )
                )
                .foregroundColor(.red)
            
            Button(action: {
                progress += 5
                if progress >= 65 {
                    progress = 0
                }
            }, label: {
                Text("Button")
            })
            
            
        }

        
    }
}

1 个答案:

答案 0 :(得分:0)

在不更改初始代码的情况下,我们的想法是在圆形进度条值更改时也旋转图像

您的代码如下所示:

struct CircularView: View {
    @State var progress:Double = 0
    var total:Double =  100
    let circleHeight:CGFloat = 217
    @State var xPos:CGFloat = 0.0
        
    @State var yPos:CGFloat = 0.0
    var body: some View {
        let pinHeight = circleHeight * 0.1
        
        VStack {
            
            Circle()
                .trim(from: 0.0, to: 0.6)
                .stroke(Color(.systemGray5),style: StrokeStyle(lineWidth: 8.0, lineCap: .round, dash: [0.1]))
                .frame(width: 278, height: 217, alignment: .center)
                .rotationEffect(.init(degrees: 162))
                .overlay(
                    Circle()
                        .trim(from: 0.0, to: CGFloat(progress) / CGFloat(total))
                        .stroke(Color.purple,style: StrokeStyle(lineWidth: 8.0, lineCap: .round, dash: [0.1]))
                        
                        .rotationEffect(.init(degrees: 162))
                        .rotation3DEffect(
                            .init(degrees: 1),
                            axis: (x: 1.0, y: 0.0, z: 0.0)
                        )
//                        .animation(.easeOut)
                        .overlay(
                            Circle()
                                
                                .frame(width: pinHeight, height: pinHeight)
                                .foregroundColor(.blue)

                                .offset(x: 107 - xPos, y: 0 + yPos)
//                                .animation(.easeInOut)
                                .rotationEffect(Angle(degrees: progress * 3.6))
                                .rotationEffect(.init(degrees: 162))
                                
                        )
                )
                .foregroundColor(.red)
                .animation(.easeOut) // Animation added here
            
            Button(action: {
                progress += 5
                if progress >= 65 {
                    progress = 0
                }
            }, label: {
                Text("Button")
            })
            
            
        }

        
    }
}

1.应用一种常见动画以获得更好的过渡

我已经在 2 个地方删除了 .animation 修饰符,并且只在父 Circle 视图上放置了一个以允许流畅的动画(您仍然可以更改并适应您想要的输出)

2.计算图像角度旋转度

执行简单的计算来确定旋转角度,我应该旋转Image视图多少度

所以,基本上是:.rotationEffect(Angle(degrees: (progress / 60) * (0.6 * 360)) => .rotationEffect(Angle(degrees: progress * 3.6))