반응형

SwiftUI에서 많이 하는 실수 - NavigationStack / NavigationLink 상태 관리 실수로 화면 전환이 꼬이는 문제

 

iOS 16+의 NavigationStack은 path 기반 내비게이션과 NavigationLink(value:)를 제공합니다.
기존 isActive/selection 패턴을 그대로 끌고 오거나, 여러 방식을 섞어 써버리면
화면이 떴다가 사라지거나, Back 동작이 꼬이는 버그가 자주 생깁니다.


1. 문제 원인

  • NavigationView 시절의 isActive 중심 패턴을 그대로 유지
  • NavigationStack + path와 NavigationLink(isActive:)를 같은 화면에서 섞어 사용
  • 프로그램적 push/pop과 NavigationLink(value:)를 동시에 제어

2. 나타나는 증상

  • 버튼을 눌렀는데 화면이 잠깐 떴다가 바로 사라짐
  • Back 버튼을 눌러도 이전 화면으로 가지 않음
  • 딥링크나 특정 상황에서 엉뚱한 화면 스택이 쌓임

3. 잘못된 코드 예시

struct RootView: View {
    @State private var isDetailActive = false

    var body: some View {
        NavigationStack {
            VStack {
                NavigationLink("상세로 이동", isActive: $isDetailActive) {
                    DetailView()
                }

                Button("프로그래매틱 이동") {
                    // ❌ isActive를 여러 곳에서 제어
                    isDetailActive = true
                }
            }
        }
    }
}

이 패턴은 단순할 때는 동작하지만,

조건부 분기/다중 화면/딥링크 등과 섞이면 상태가 쉽게 꼬입니다.


4. 올바른 코드 예시 (path 기반)

struct Detail: Hashable {
    let id: Int
}

struct RootView: View {
    @State private var path: [Detail] = []

    var body: some View {
        NavigationStack(path: $path) {
            VStack {
                Button("ID 1 상세로 이동") {
                    path.append(Detail(id: 1))
                }
                Button("ID 2 상세로 이동") {
                    path.append(Detail(id: 2))
                }
            }
            .navigationDestination(for: Detail.self) { detail in
                DetailView(detail: detail)
            }
        }
    }
}

struct DetailView: View {
    let detail: Detail
    var body: some View {
        Text("Detail id: \(detail.id)")
    }
}
  • push: path.append(...)
  • pop: path.removeLast() 또는 path = []

로 명확하게 제어할 수 있습니다.


5. 정리 및 팁

  • 복잡한 네비게이션이 예상된다면 무조건 NavigationStack + path + navigationDestination(for:) 패턴을 우선 고려합니다.
  • isActive/selection 스타일 NavigationLink는 “한 단계 짜리 단순 화면 전환” 정도로만 제한적으로 사용합니다.
  • 네비게이션 상태를 TCA/Router 등으로 한 곳에서 관리하면 딥링크/리다이렉트 처리도 한결 쉬워집니다.
반응형
Posted by 까칠코더
,