【问题标题】:Animate changes to Array - SwiftUI ForEach动画更改数组 - SwiftUI ForEach
【发布时间】:2022-11-15 08:06:25
【问题描述】:

我是来自 UIKit 的 SwiftUI 新手。我正在努力实现以下目标:

  • 给定视图模型中的一组可变状态,表示当前进度将显示在Circle上,使用trim(from:to:)
  • 循环遍历每个项目以呈现一个具有当前进度的圆圈,并动画显示从旧位置到新位置的变化
  • 视图模型将定期更新作为 ObservableObject 中的 @Published 值的数组。

我设置了一个看起来像这样的演示视图


@StateObject var demoViewModel: DemoViewModel = DemoViewModel()

var body: some View {
            ForEach(demoViewModel.progress, id: \.self) { progress in
                Circle()
                    .trim(from: 0, to: progress.progress)
                     .stroke(style: StrokeStyle(lineWidth: 15, lineCap: .round))
                     .foregroundColor(.red)
                     .frame(width: 100)
                     .rotationEffect(.degrees(-90))
                     .animation(.linear(duration: 1), value: demoViewModel.progress)
            }
        }

和这样的测试视图模型

class DemoViewModel: ObservableObject {

    @Published var progress: [Demo] = [.init(progress: 0)]

    struct Demo: Hashable {
        let progress: Double
    }

    init() {
        Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
            let current = self.progress[0]

            if current.progress < 1 {
                self.progress[0] = .init(progress: current.progress + 0.1)
            }

        }
    }
}

为了演示,数组只有一项。我所期望的是在每次迭代中都会将一个新值写入数组中的项目,这会触发动画为该值设置动画。实际发生的是进度更新,但它会跳转到每个新值而没有动画。

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    试试这种方法,其中init() 中的self.demos[0].progress 更新而不是在每次滴答时创建一个新的Demo(...)

    注意,还修改了一些其他的东西,比如 .animation(...value:..)尤其是ForEach 循环,添加了 Demo 唯一 ID。

    struct ContentView: View {
        @StateObject var demoViewModel: DemoViewModel = DemoViewModel()
        
        var body: some View {
            VStack {
                ForEach(demoViewModel.demos) { demo in  // <-- here
                    Circle()
                        .trim(from: 0, to: demo.progress)
                        .stroke(style: StrokeStyle(lineWidth: 15, lineCap: .round))
                        .foregroundColor(.red)
                        .frame(width: 100)
                        .rotationEffect(.degrees(-90))
                        .animation(.linear(duration: 1), value: demo.progress) // <-- here
                }
            }
        }
    }
    
    class DemoViewModel: ObservableObject {
        @Published var demos:[Demo] = [Demo(progress: 0)]
        
        struct Demo: Identifiable, Hashable {  // <-- here
            let id = UUID()  // <-- here
            var progress: Double  // <-- here
        }
        
        init() {
            Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
                if self.demos[0].progress < 1 {
                    self.demos[0].progress = self.demos[0].progress + 0.1 // <-- here
                }
            }
        }
       
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多