为 ForEach 循环元素添加动画 (SwiftUI) [英] Add animations to ForEach loop elements (SwiftUI)

查看:26
本文介绍了为 ForEach 循环元素添加动画 (SwiftUI)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there any way I can add animation when elements of a ForEach loop appears or disappears?

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

I have tried using withAnimation{} and .animation() in many ways but they didn't seem to work

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

Here is some code (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

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

As can be seen below, without animations everything feels super abrupt. Any solution is really appreciated

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

Important notice: The layout should change in the same way List does when the number of elements changes. For example, every object automatically moves top when a top object is deleted

推荐答案

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

It looks like this problem is still up to day (Xcode 11.4), because by just copy-pasting the observed effect is the same. So, there are a couple of problems here: first, it needs to setup combination of animation and transition correctly; and, second, the ForEach container have to know which exactly item is removed, so items must be identified, instead of indices, which are anonymous.

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

As a result we have the following effect (transition/animation can be others):

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

这篇关于为 ForEach 循环元素添加动画 (SwiftUI)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆