rundfunk47 / stinsen

Coordinators in SwiftUI. Simple, powerful and elegant.
MIT License
822 stars 87 forks source link

Problem with .push transition. #106

Closed amineahmmouch closed 1 year ago

amineahmmouch commented 1 year ago

Hi, i just discover Stinsen and i think it's the best implemetation of Coordinator pattern in SwiftUI. Congratulations.

Here is my problem,

I have two views SignInView and ForgotPasswordView, and i want to perform push from SignInView to ForgetPassword, but its doesn't perform push animation neither it doesn't switch to the second view (ForgetPasswordView). Note that .modal and .fullscreen transitions work the problem occur just for .push.

Did i implement the flow wrong ?

Thanks in advance.

Here is my code :

struct SignInView: View {
    var body: some View {
            ZStack(alignment: .bottom) {
                VStack {
                    ...

                        Text("Forget password")
                            .foregroundColor(Color.white.opacity(0.7))
                            .accessibilityIdentifier("SIGNIN_FORGET_PASSWORD_BUTTON")
                            .onTapGesture {
                                signInRouter.route(to: \.forgetPassword)
                            }

                            .....
                }
          }
    }
}
protocol SignInCoordinator: AnyObject {
    func pushToForgetPassword()
}
final class DefaultSignInCoordinator: SignInCoordinator, NavigationCoordinatable {
    var stack: NavigationStack<DefaultSignInCoordinator> = NavigationStack(initial: \.start)

    @Root var start = makeStart
    @Route(.push) var forgetPassword = makeForgetPassword

    lazy var routerStorable: SignInCoordinator = self

    func makeStart() -> some View {
        return SignInView()
    }

    func makeForgetPassword() ->  DefaultForgetPasswordCoordinator {
        return DefaultForgetPasswordCoordinator()
    }

    func pushToForgetPassword() {
        self.route(to: \.forgetPassword)
    }
}
struct ForgetPasswordFormView: View {

    @EnvironmentObject private var signInRouter: DefaultSignInCoordinator.Router

    var body: some View {
            GeometryReader { _ in
                ZStack(alignment: .top) {
                    HStack {
                        Button(action: {
                            signInRouter.popToRoot()
                        }) {
                            Image(systemName: "arrowshape.turn.up.left.fill")
                                .resizable()
                                .frame(width: 40, height: 40)
                                .foregroundColor(.white)
                                .padding()
                        }
                        Spacer()
                    }

                    .......

            }
    }
}
protocol ForgetPasswordCoordinator: AnyObject {
    func popToSignIn()
}
final class DefaultForgetPasswordCoordinator: ForgetPasswordCoordinator, NavigationCoordinatable {

    var stack = NavigationStack(initial: \DefaultForgetPasswordCoordinator.start)

    @Root var start = makeStart

    func makeStart() -> some View {
        ForgetPasswordView()
    }

    func popToSignIn() {

    }
}
LePips commented 1 year ago

You need to make sure that your NavigationCoordinatable instances are wrapped in a NavigationViewCoordinator.

e.g:

// 1 - wherever you instantiate DefaultSignInCoordinator
NavigationViewCoordinator(DefaultSignInCoordinator())

// 2 - if you want to push views in DefaultForgetPasswordCoordinator, also needs to be wrapped
func makeForgetPassword() -> NavigationViewCoordinator<DefaultForgetPasswordCoordinator> {
    NavigationViewCoordinator(DefaultForgetPasswordCoordinator())
}
amineahmmouch commented 1 year ago

You are right. I didn't wrap the sign in coordinator in NavigationViewCoordinator. NavigationViewCoordinator(DefaultSignInCoordinator()).view()

Thank you so much for your help. Have a nice day.