TransWikia.com

Animation does not work when passing function argument to child view

Stack Overflow Asked by user1354934 on January 3, 2022

I have a parent view that can show one of two views:

struct LoginSubView: View {
    @State private var loginSubView: LoginSubViews = .login
    
    func setLoginSubView(_ view: LoginSubViews) {
        withAnimation {
            self.loginSubView = view
        }
    }
    
    var body: some View {
        VStack {
            if self.loginSubView == .signup {
                SignupView(setLoginSubView: self.setLoginSubView)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)).animation(.default))
            } else {
                LoginView(setLoginSubView: self.setLoginSubView)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)).animation(.default))
            }
        }
        .padding(.horizontal, 16)
        .keyboardObserving()
    }
}

The setLoginSubView() is called by those child views to switch views.

Unfortunately, it no longer animates when I pass the function and call it from the child. It switches instantly. However, it does work if I do this:

struct LoginSubView: View {
    @State private var loginSubView: LoginSubViews = .login
    
    // removed setLoginSubview()
    
    var body: some View {
        VStack {
            if self.loginSubView == .signup {
                SignupView(setLoginSubView: self.setLoginSubView)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)).animation(.default))
                
                // Added it here
                Button(action: {
                    withAnimation {
                        self.loginSubView = .login
                    }
                }) {
                    Text("Already have an account? Sign in").animation(nil)
                }
            } else {
                LoginView(setLoginSubView: self.setLoginSubView)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)).animation(.default))
                // And added this here
                Button(action: {
                    withAnimation {
                        self.loginSubView = .signup
                    }
                }) {
                    Text("Don't have an account? Sign up").animation(nil)
                }
            }
        }
        .padding(.horizontal, 16)
        .keyboardObserving()
    }
}

How can I have the animation work when passing this function to the child?

One Answer

Move animation to container (tested with Xcode 12 / iOS 14)

var body: some View {
    VStack {
        if self.loginSubView == .signup {
            SignupView(setLoginSubView: self.setLoginSubView)
                .transition(AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading)))
        } else {
            LoginView(setLoginSubView: self.setLoginSubView)
                .transition(AnyTransition.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
        }
    }
    .animation(.default)          // << here !!
    .padding(.horizontal, 16)
    .keyboardObserving()
}

Answered by Asperi on January 3, 2022

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP