向 ForEach 添加项目并为下面的项目设置良好的动画,这样它就不会跳跃

问题描述 投票:0回答:1

当我向数组添加元素时,我试图让它很好地动画化。

目前添加foreach元素后按钮会向下跳转。

这是我的代码:

import SwiftUI

class ForEachAnimationViewModel: ObservableObject {
    @Published var array: [String] = []
    var count = 5
    
    init() {
        array = (0..<count).map({ "Element \($0)" })
    }
    
    func addMore() {
        let newItems = (count..<count+5).map({ "Element \($0)" })
        array.append(contentsOf: newItems)
    }
}

struct ForEachAnimationView: View {
    @ObservedObject var viewModel: ForEachAnimationViewModel
    var body: some View {
        ScrollView {
            ForEach(viewModel.array, id: \.self) { element in
                Text(element)
            }
            
            Button(action: {
                withAnimation {
                    viewModel.addMore()
                }
            }) {
                Text("Button")
            }
        }
    }
}

#Preview {
    ForEachAnimationView(viewModel: ForEachAnimationViewModel())
}

swiftui swiftui-animation swiftui-foreach
1个回答
0
投票

正如评论中提到的,当您添加更多项目时,您不会更新

count
,因此这会导致控制台中显示重复 ID 的错误。解决方法之一是更改函数
addMore
,使新 id 基于现有计数:

func addMore() {
    let count = array.count
    let newItems = (count..<count+5).map({ "Element \($0)" })
    array.append(contentsOf: newItems)
}

然后,可以通过这些更改来改进动画:

  • .animation
     添加 
    ScrollView
  • 修饰符
  • .transition
    项目添加
    Text
    修饰符
  • minWidth
    上设置
    Text
    ,以避免当一行宽度大于前一行宽度时出现换行问题。
struct ForEachAnimationView: View {
    @ObservedObject var viewModel: ForEachAnimationViewModel
    var body: some View {
        ScrollView {
            ForEach(viewModel.array, id: \.self) { element in
                Text(element)
                    .frame(minWidth: 200)
                    .transition(.opacity)
            }
            Button("Button") {
                viewModel.addMore()
            }
        }
        .animation(.easeIn(duration: 1), value: viewModel.array)
    }
}

您可以尝试其他类型的过渡,但如果您想看到行一行一行地出现,最好逐行添加它们,而不是一次添加 5 行。

© www.soinside.com 2019 - 2024. All rights reserved.