기존 닫기는 fullScreenCover
에 맞게 dismiss
로 해주고 있었는데, 이제는Navigation
으로 대체를 하면서 dismiss
가 안먹히게 된 상황!
그래서 기존 NavigationManager.setAuthRoot
를 통해서 RootView
를 전환시켜주려했는데, 다음과 같이 계속 유저타입선택 페이지에서 무한히 머무르는 버그가 발생했다.
userTypeSelection의 닫기버튼
ToolbarItem(placement: .navigationBarTrailing) { Button("닫기") { navigationManager.setAuthRoot() } }
SignInView에서 로그인(회원가입)시 로직
await MainActor.run { isLoading = false // 기존 코드 navigationManager.rootview = .auth(.userTypeSelection) // 변경코드 navigationManager.navigate(to: .userTypeSelection) }
NavigationManager 파일은 다음과 같다.
navigate
를 통해서 path에 넣어주는 식이다.
Navigation Manager
class NavigationManager: ObservableObject { @Published var path = NavigationPath() @Published var rootView: AppRootView = .auth(.login) // 같은이름 navigate 3개를 하나로 합친 상태 func navigate<T: Hashable>(to destination: T) { path.append(destination) } func popToRoot() { path = NavigationPath() } func pop() { path.removeLast() } func setMainRoot(userType: UserType) { path = NavigationPath() switch userType { case .mentor: rootView = .mentor(.home) case .learner: rootView = .learner(.home) } } func setAuthRoot() { path = NavigationPath() rootView = .auth(.login) } }
SignInView에서 신규 유저일 경우(회원가입이 진행되어야함) 버그가 발생한다.
if isExistingUser { //이미 있는 유저면 ..
checkUserType()
} else {
navigationManager.rootView = .auth(.userTypeSelection)
}
신규 유저로 판단되면 RootView를 .auth(.userTypeSelection)
으로 바꾸는데, 닫기 버튼을 누르면 다시.auth(.login)
으로 돌아가고, 이때 SignInView
가 다시 그려진다.
문제는 이 SignInView에서 로그인 로직이 다시 실행되면서 동일하게 .auth(.userTypeSelection)
으로 이동해 무한 루프가 발생했던 것이다.
두 동작이 반복되면서 루프에 빠지게 된다
1. 닫기 → .auth(.login)
2. 로그인 로직 재실행 → .auth(.userTypeSelection)
→ 무한 반복
⸻
기존에는 rootView 자체를 덮어씌우는 방식이었지만, 아래처럼 NavigationStack의 path
에만 뷰를 추가하는 방식으로 해결해주었다.
navigationManager.navigate(to: .userTypeSelection)
이렇게 하면 rootView는 여전히 .auth(.login)
으로 유지되고, SignInView
는 재실행되지 않는다.
따라서 userTypeSelection
에서 닫기 버튼을 눌렀을 때 더 이상 루프가 발생하지않고, 잘 수행되는 것을 확인할 수 있다.