SwiftUI Circle View 动画故障

Posted

技术标签:

【中文标题】SwiftUI Circle View 动画故障【英文标题】:SwiftUI Circle View animation glitch 【发布时间】:2021-11-09 18:15:06 【问题描述】:

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。 【参考方案1】:

目前还不清楚,可能是由于形状的未定义大小作为一种性质......无论如何,似乎使用绘图组解决了这个问题。

这是一个固定的代码。使用 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()
        
    

【讨论】:

以上是关于SwiftUI Circle View 动画故障的主要内容,如果未能解决你的问题,请参考以下文章

从 RoundedRectangle 到 Circle 的 SwiftUI 缩放效果

ScrollView + NavigationView 动画故障 SwiftUI

为 ForEach 循环元素添加动画 (SwiftUI)

是啥导致 SwiftUI 嵌套的 View 项目在初始绘制后出现跳跃动画?

SwiftUI 视图层次结构中较高的动画覆盖嵌套动画

Spring() 动画完成后 SwiftUI 执行操作