SwiftUI动态添加子视图,但动画不起作用 [英] SwiftUI add subview dynamically but the animation doesn't work
问题描述
我想在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")
}
}
}
}
请注意两件事:
- 您上面的两个示例是不同的,这就是为什么您得到不同结果的原因.首先,将过渡和动画应用于DetailView,然后使用AnyView对其进行类型擦除.第二种类型是使用AnyView擦除DetailView,然后应用过渡和动画.
- 我宁愿使用AnyView和类型擦除来将条件逻辑封装在
Group
视图中.然后您返回的类型是Group
,它将正确设置动画. - 如果您希望在子视图的两种可能性上使用不同的动画,则现在可以将它们直接应用于
DetailView()
或Text("test")
.
- 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.
- Rather that using AnyView and type-erasure, I prefer to encapsulate the conditional logic inside of a
Group
view. Then the type you return isGroup
, which will animate properly. - If you wanted different animations on the two possibilities for your subview, you can now apply them directly to
DetailView()
orText("test")
.
更新
Group
方法仅适用于if
,elseif
和else
语句.如果要使用开关,则必须将每个分支都包装在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屋!