xTwisteDx
xTwisteDx

Reputation: 2472

SwiftUI: How do I transition gracefully when parent view changes?

I have a view that starts setup like this.

var body: some View {
    switch appState.userFlow {
    case .onboarding:
        Text("Not Yet Implemented")
    case .login:
        LandingPageView()
    case .home:
        HomeScreenView()
    }
}

In each of those userFlow's I change the appState utilizing an @EnvironmentObject Whenever the object changes its state, the view blinks away and the new one is presented. This looks abrupt and ugly as it stands.

I attempted to do something along the lines of this. Which had no effect. What is the proper way to handle a transition when used in this context?

LandingPageView().transition(.opacity)

Upvotes: 1

Views: 981

Answers (1)

aheze
aheze

Reputation: 30336

The .transition needs to be applied to the container of the views that you want to switch over, so you'll need to embed your switch inside a Group, VStack, or similar.

Also, you need to have either a .animation(.default) on the container, or change appState.userFlow inside a withAnimation {} block to actually animate the change.

enum UserFlow {
    case onboarding
    case login
    case home
}
struct ContentView: View {
    @State var userFlow = UserFlow.home
    var body: some View {
        
        /// container
        Group {
            
            switch userFlow {
            case .onboarding:
                Text("Not Yet Implemented")
            case .login:
                Text("Login page")
            case .home:
                Text("Home page")
            }
            
        }
        .animation(.default) /// also need Animation
        .transition(.opacity)
        
        /// for testing
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                userFlow = .login
            }
        }
    }
}

Result:

Text "Home page" fades to "Login page"

Upvotes: 2

Related Questions