SwiftUI Transition Animation is Applied to Elements Inside View Separately

502 Views Asked by At

I'm having a very strange issue with my SwiftUI transitions/animations. My intention is to slide whole views in/out, but it seems like the animation is applied to the elements inside of the view separately as well as the whole view. The result is very strange and unpleasant - the text and button inside the view end up moving at different speeds and separately when they should be fixed in place and move with their parent view. Can anyone explain why this is happening? Thanks!

Entrypoint.swift

import SwiftUI

enum Page {
    case login, onboarding, home
}

struct Entrypoint: View {
    @State var onboarding: Bool = true
    @State var page: Page = .login
    
    func finishLogin() {
        page = .onboarding
    }

    func finishOnboarding() {
        page = .home
    }
    
    // Slide transition
    let transition = AnyTransition.asymmetric(insertion: .move(edge: .trailing), removal: .offset(x: -24))

    var body: some View {
        ZStack {
            switch page {
            case .login:
                LoginView(finish: finishLogin)
                    .transition(transition)
            case .onboarding:
                OnboardingView(finish: finishOnboarding)
                    .transition(transition)
            case .home:
                RootView()
                    .transition(transition)
            }
        }.animation(.easeInOut, value: page)
    }
}

LoginView.swift

import SwiftUI

struct LoginView: View {
    var finish: () -> Void

    init(finish: @escaping () -> Void) {
        self.finish = finish
    }
    
    var body: some View {
        VStack {
            Group {
                Text("Hello, World!")
                
                Button(action: {
                    finish()
                }) {
                    Text("Login")
                }
            }.frame(minWidth: 0, maxWidth: .infinity)
            
        }.background(Color.green)
        .frame(minWidth: 0, maxWidth: .infinity)
    }
}
0

There are 0 best solutions below