SwiftUI 圆形视图动画毛刺。

3

glitch

import SwiftUI

struct CircularProgressView: View {
    
    @Binding var progress: Float
    private let strokeStyle = StrokeStyle(lineWidth: 30.0, lineCap: .round, lineJoin: .round)
    private let rotation = Angle(degrees: 270.0)
        
    var body: some View {
        ZStack {
            Circle()
                .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
                .stroke(style: strokeStyle)
                .opacity(0.2)
                .foregroundColor(Color.black)
                .rotationEffect(rotation)
                .offset(x: 0, y: 10)
                            
            Circle()
                .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
                .stroke(style: strokeStyle)
                .opacity(1)
                .foregroundColor(Color.white)
                .rotationEffect(rotation)
                
        }
        .animation(.linear(), value: progress)
    }
}

struct CircularProgressView_Previews: PreviewProvider {
    static var previews: some View {
        OtherView(progress: 0.6)
    }
    
    struct OtherView : View {
        
        @State var progress : Float = 0.0
        
        var body: some View {
            ZStack {
                Color.yellow
                VStack {
                    CircularProgressView(progress: self.$progress)
                        .padding(50)
                    Button(action: {
                        if(progress >= 1) {
                            progress = 0
                        } else {
                            progress += 0.1
                        }
                    }) {
                        Text("try me")
                            .frame(width: 200, height: 50)
                            .overlay(
                                RoundedRectangle(cornerRadius: 20)
                                    .stroke(Color.blue, lineWidth: 2)
                            )
                            .padding(.bottom, 100)
                            
                    }
                }
            }.ignoresSafeArea()
        }
    }
}

可能的原因是什么?

为什么不使用路径呢?我认为那会更容易和更好。对于黑色圆形,您可以使用阴影!使用drawingGroup是有帮助的,因为在视图中编码有些错误或者不太好。在正常编码中,我们不需要drawingGroup - ios coder
1个回答

4

由于形状的大小未定义,具体情况不清楚......无论如何,使用绘图组可以解决问题。

以下是修复后的代码。 已在Xcode 13 / iOS 15上进行测试。

演示

struct CircularProgressView: View {

    @Binding var progress: Float
    private let strokeStyle = StrokeStyle(lineWidth: 30.0, lineCap: .round, lineJoin: .round)
    private let rotation = Angle(degrees: 270.0)

    var body: some View {
        ZStack {
            Group {
                Circle()
                    .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
                    .stroke(style: strokeStyle)
                    .opacity(0.2)
                    .foregroundColor(Color.black)
                    .rotationEffect(rotation)
                    .offset(x: 0, y: 10)
                Circle()
                    .trim(from: 0.0, to: CGFloat(min(self.progress, 1.0)))
                    .stroke(style: strokeStyle)
                    .opacity(1)
                    .foregroundColor(Color.white)
                    .rotationEffect(rotation)
            }
            .padding()    // << compensate offset within own bounds
        }
        .drawingGroup()   // << here !!
        .animation(.linear, value: progress)
    }
}

struct CircularProgressView_Previews: PreviewProvider {
    static var previews: some View {
        OtherView(progress: 0.6)
    }

    struct OtherView : View {

        @State var progress : Float = 0.0

        var body: some View {
            ZStack {
                Color.yellow
                VStack {
                    CircularProgressView(progress: self.$progress)
                        .padding()
                    Button(action: {
                        if(progress >= 1) {
                            progress = 0
                        } else {
                            progress += 0.1
                        }
                    }) {
                        Text("try me")
                            .frame(width: 200, height: 50)
                            .overlay(
                                RoundedRectangle(cornerRadius: 20)
                                    .stroke(Color.blue, lineWidth: 2)
                            )
                            .padding(.bottom, 100)
                    }
                }
            }.ignoresSafeArea()
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接