问题
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!
回答1:
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")
}
}
}
}
Note two things:
- 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")
.
Update
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.
来源:https://stackoverflow.com/questions/58160011/swiftui-add-subview-dynamically-but-the-animation-doesnt-work