I’m implementing a very simple view (ChildView) that will slide up from the bottom of ParentView when a button is tapped. I’ve reproduced the issue below in a minimal example.
struct ChildView: View {
@Binding var foo: String?
var body: some View {
HStack {
if case .some = foo {
Text("Foo")
}
Spacer()
Text("Bar")
}
.offset(y: foo != nil ? 0 : UIScreen.main.bounds.height)
}
}
struct ParentView: View {
@State private var foo: String?
var body: some View {
ZStack {
Button(action: {
withAnimation {
foo = "Foo"
}
}) {
Text("Tap me")
}
ChildView(foo: $foo)
}.frame(width: 300, height: 500)
}
}
I pass a binding into ChildView that is a simple String? here, but ultimately it will be an enum instance which I will switch on inside ChildView.
The problem is that Text("Foo") inside ChildView doesn’t slide up from the bottom, but rather fades in place. Text("Bar") slides correctly, and the only difference is that the former touches the foo binding. See GIF below:
One can observe the same thing if foo was an enum and we switched on it.
What is going on?
I saw this question, but the accepted answer didn’t work for me.
>Solution :
When the binding changes, the ChildView changes two things: Show "foo" which hadn’t been there before, and change the offset of anything else to 0.
So animation will only work on what has been there before. i.e. "Bar".
But you can change the value of elements, that are already there:
struct ChildView: View {
@Binding var foo: String?
var body: some View {
HStack {
Text(foo ?? "")
Spacer()
Text("Bar")
}
.offset(y: foo != nil ? 0 : UIScreen.main.bounds.height)
}
}
