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

Ngu*_*Hào 12 swift swiftui

当 ForEach 循环的元素出现或消失时,有什么方法可以添加动画?

我曾尝试以多种方式使用 withAnimation{} 和 .animation() 但它们似乎不起作用

这是一些代码(Xcode 11 beta 5):

import SwiftUI

struct test: View {
    @State var ContentArray = ["A","B","C"]
    var body: some View {
        ScrollView{
        VStack{
            ForEach(ContentArray.indices, id: \.self){index in
                ZStack{
                // Object
                    Text(self.ContentArray[index])
                    .frame(width:100,height:100)
                    .background(Color.gray)
                    .cornerRadius(20)
                    .padding()
                //Delete button
                    Button(action: {
                      self.ContentArray.remove(at: index)
                    }){
                    Text("?")
                    .foregroundColor(.white)
                    .frame(width:40,height:40)
                    .background(Color.red)
                    .cornerRadius(100)
                   }.offset(x:40,y:-40)
             }
           }
         }   
       }
   }
}


#if DEBUG
struct test_Previews: PreviewProvider {
    static var previews: some View {
        test()
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

如下所示,没有动画,一切都感觉非常突然。任何解决方案都非常感谢

重要提示:当元素数量发生变化时,布局应该以与 List 相同的方式发生变化。例如,删除顶部对象时,每个对象都会自动移至顶部

预期结果

结果不好

Asp*_*eri 7

看起来这个问题仍然存在(Xcode 11.4),因为通过复制粘贴观察到的效果是相同的。所以,这里有几个问题:首先,需要正确设置动画和过渡的组合;其次,ForEach容器必须知道到底删除了哪个项目,因此必须识别项目,而不是匿名的索引。

\n

结果我们有以下效果(过渡/动画可以是其他):

\n

演示

\n
struct TestAnimationInStack: View {\n    @State var ContentArray = ["A","B","C", "D", "E", "F", "G", "I", "J"]\n    var body: some View {\n        ScrollView{\n        VStack{\n            ForEach(Array(ContentArray.enumerated()), id: \\.element){ (i, item) in // << 1) !\n                ZStack{\n                // Object\n                    Text(item)\n                    .frame(width:100,height:100)\n                    .background(Color.gray)\n                    .cornerRadius(20)\n                    .padding()\n                //Delete button\n                    Button(action: {\n                       withAnimation { () -> () in              // << 2) !!\n                           self.ContentArray.remove(at: i)         \n                       }\n                    }){\n                    Text("\xe2\x9c\x95")\n                    .foregroundColor(.white)\n                    .frame(width:40,height:40)\n                    .background(Color.red)\n                    .cornerRadius(100)\n                   }.offset(x:40,y:-40)\n                }.transition(AnyTransition.scale)              // << 3) !!!\n           }\n         }\n       }\n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这对于删除来说效果很好,但是当执行 #append 时,过渡动画不起作用。 (2认同)