Animating Bindings in SwiftUI

Viewed 996

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)
    }
}
2 Answers

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))
    }
}

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)
    }
}
Related