Reputation: 987
I have the following code which partially shows or hides the Test
view depending on a Binding<Bool>
. I can wrap the testVisible.toggle()
call in a withAnimation
, however, ideally I would like to ensure that visible
binding is always animated, even when called without a withAnimation
. How can I make sure that whenever visible
binding is changed, the change is animated?
struct ContentView: View {
@State var testVisible: Bool = true
var body: some View {
ZStack {
Color.white
.onTapGesture {
testVisible.toggle()
}
Test(visible: $testVisible)
}
}
}
struct Test: View {
@Binding var visible: Bool
var body: some View {
Text("Test")
.opacity(visible ? 0.5 : 0)
}
}
Upvotes: 4
Views: 2782
Reputation: 30575
You have a mistake, in Test: View
it should be a let visible
not a @Binding var
. let
is for read access and @Binding var
is when you need write access which you don't. This version animates in and out correctly:
struct ContentView3: View {
@State var testVisible: Bool = true
var body: some View {
ZStack {
Color.white
.onTapGesture {
withAnimation {
testVisible.toggle()
}
}
Test(visible: testVisible)
}
}
}
struct Test: View {
let visible: Bool
var body: some View {
Text("Test")
.opacity(visible ? 0.5 : 0)
}
}
Upvotes: 0
Reputation: 520
The simple .animation()
modifier is deprecated in iOS 15 and macOS 12. You need to add a value, which the animation is based on:
struct Test: View {
@Binding var visible: Bool
var body: some View {
Text("Test")
.opacity(visible ? 0.5 : 0)
.animation(.linear(duration: 0.5), value: visible)
}
}
Upvotes: 4
Reputation: 154593
Add a .animation()
modifier to the Text
view:
struct Test: View {
@Binding var visible: Bool
var body: some View {
Text("Test")
.opacity(visible ? 0.5 : 0)
.animation(.linear(duration: 0.5))
}
}
Upvotes: 4