将函数参数传递给子视图时,动画不起作用

时间:2020-07-24 20:03:25

标签: ios swift swiftui

我有一个父视图,可以显示两个视图之一:

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

这些子视图调用setLoginSubView()来切换视图。

不幸的是,当我传递函数并从孩子那里调用它时,它不再具有动画效果。它立即切换。但是,如果这样做,它确实可以工作:

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

将此功能传递给孩子时如何制作动画?

1 个答案:

答案 0 :(得分:2)

将动画移至容器(已通过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()
}