SwiftUI动态添加子视图,但动画不起作用 [英] SwiftUI add subview dynamically but the animation doesn't work

查看:157
本文介绍了SwiftUI动态添加子视图,但动画不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在SwiftUI中创建一个视图,该视图动态地添加子视图并带有动画.

I would like to create a view in SwiftUI that add a subview dynamically and with animation.

struct ContentView : View {
    @State private var isButtonVisible = false

    var body: some View {
        VStack {
            Toggle(isOn: $isButtonVisible.animation()) {
                Text("add view button")
            }

           if isButtonVisible {
                 AnyView(DetailView())
                      .transition(.move(edge: .trailing))
                      .animation(Animation.linear(duration: 2))
             }else{
                    AnyView(Text("test"))
            }
        }
    }
}

上面的代码可以很好地与动画配合使用.但是,当我将视图选择部分移动到函数中时,动画不再起作用(因为我想动态添加不同的视图,因此,我将逻辑放在函数中.)

The above code works fine with the animation . however when i move the view selection part into a function, the animation is not working anymore (since i want to add different views dynamically, therefore, I put the logic in a function.)


struct ContentView : View {
    @State private var isButtonVisible = false
    var body: some View {
        VStack {
            Toggle(isOn: $isButtonVisible.animation()) {
                Text("add view button")
            }

            subView().transition(.move(edge: .trailing))
                     .animation(Animation.linear(duration: 2))   
    }

     func subView() -> some View {
         if isButtonVisible {
             return AnyView(DetailView())
         }else{
            return AnyView(Text("test"))
        }
    }
}

对我来说看起来完全一样,但是,我不明白为什么他们会有不同的结果.有人可以解释一下为什么吗?还有更好的解决方案?非常感谢!

it looks totally the same to me, however, i don't understand why they have different result. Could somebody explain me why? and any better solutions? thanks alot!

推荐答案

下面是您的代码,已对其进行了修改,使其可以正常工作:

Here's your code, modified so that it works:

struct ContentView : View {
    @State private var isButtonVisible = false

    var body: some View {
        VStack {
            Toggle(isOn: $isButtonVisible.animation()) {
                Text("add view button")
            }

            subView()
                .transition(.move(edge: .trailing))
                .animation(Animation.linear(duration: 2))
        }
    }

    func subView() -> some View {
        Group {
            if isButtonVisible {
                DetailView()
            } else {
                Text("test")
            }
        }
    }
}

请注意两件事:

  1. 您上面的两个示例是不同的,这就是为什么您得到不同结果的原因.首先,将过渡和动画应用于DetailView,然后使用AnyView对其进行类型擦除.第二种类型是使用AnyView擦除DetailView,然后应用过渡和动画.
  2. 我宁愿使用AnyView和类型擦除来将条件逻辑封装在Group视图中.然后您返回的类型是Group,它将正确设置动画.
  3. 如果您希望在子视图的两种可能性上使用不同的动画,则现在可以将它们直接应用于DetailView()Text("test").
  1. Your two examples above are different, which is why you get different results. The first applies a transition and animation to a DetailView, then type-erases it with AnyView. The second type-erases a DetailView with AnyView, then applies a transition and animation.
  2. Rather that using AnyView and type-erasure, I prefer to encapsulate the conditional logic inside of a Group view. Then the type you return is Group, which will animate properly.
  3. If you wanted different animations on the two possibilities for your subview, you can now apply them directly to DetailView() or Text("test").

更新

Group方法仅适用于ifelseifelse语句.如果要使用开关,则必须将每个分支都包装在AnyView()中.但是,这会中断过渡/动画.当前无法使用switch 设置自定义动画.

The Group method will only work with if, elseif, and else statements. If you want to use a switch, you will have to wrap each branch in AnyView(). However, this breaks transitions/animations. Using switch and setting custom animations is currently not possible.

这篇关于SwiftUI动态添加子视图,但动画不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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