ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS/SwiftUI] NavigationStack을 왜 사용하는가?
    Apple🍎/iOS 2024. 9. 4. 01:48

    NavigationStack으로 link를 타면서 화면 전환을 하다가,,,
    화면 전환을 하면서 action을 취해야하는 순간이 있었는데 이를 찾다가 .navigationDestination을 봤고....
    Router 구조체를 만들어서 navigation을 정리하는 것을 보며

    NavigationStack은 도대체 왜 나타나게 된건지,
    어떻게 제대로 사용하는 건지를 찾아보게 됐다.

    NavigationStack & Link로 사용하면 안되는건가?

    원래는 아래와 같이 NavigationLink만 사용해도, 원하는 화면으로 이동 가능하다.

    import SwiftUI
    
    struct ContentView: View {
        var body: some View {
            NavigationStack {
                VStack {
                    Text("Welcome to the main screen")
                    NavigationLink("Go to Details", destination: DetailView())
                }
                .navigationTitle("Home")
            }
        }
    }

    클릭시 다음 화면으로 전환되는 것이 기능이기 때문에,,

    하지만 이러면 WWDC22에서 발표한 NavigationStack을 100% 활용하지 못한다.

    NavigationStack이 나온 이유는,
    이전에 NavigationView로 사용했을 때는 Link에 있는 isActive를 통해 조건을 확인 후 View를 보여주는 방식으로 작동했다.

    하지만 이렇게 되니 dismiss로 화면을 내리고 하는 도중에 isActive에 해당하는 flag 작동이 잘 안되면 화면 간의 관리가 어렵다고 복잡하다고 느껴졌다.

    💡 이를 위해 나타난 게 NavigationStack 이다.

    NavigationStack & Destination

    NavigationDestination

    NavigationDestination의 선언 방식은 3가지 이다.
    모두 NavigationLink 와 함께 사용된다.

    1. navigationDestination(for:destination:)
    2. navigationDestination(isPresented:destination:)
    3. navigationDestination(item:destination:)

    특히 첫번째인, navigationDestination(for:)특정 데이터 타입으로 목적지 뷰에 영향이 간다거나,경로에 따라 동적으로 탐색 경로를 설정할때 사용한다.
    이 방식을 사용해야만 NavigationStack의 Path 개념을 사용할 수 있다.

    우선, navigationDestination(for:)의 예시를 본다면,
    아래처럼 Color 데이터에 따라 ColorDetail 뷰가 달라진다던지,,,

    NavigationStack {
        List {
            NavigationLink("Mint", value: Color.mint)
            NavigationLink("Pink", value: Color.pink)
            NavigationLink("Teal", value: Color.teal)
        }
        .navigationDestination(for: Color.self) { color in
            ColorDetail(color: color)
        }
        .navigationTitle("Colors")
    }

    NavigationStack의 Path배열은 어떤 타입이어도 다 담을 수 있도록 [Binding <Data>] 로 설정되어있다.
    NavigationDestination(for:) 에 담긴 데이터가 Path에 담기는 것이다.

    예를 들면,

     

    위의 코드는 결국 아래처럼 item에
    Apple Pie → 그 안에 또 navigationDestination에 Pie Crust 가 들어가는 것이다.

    .navigationDestination(for: Item.self){ item in 
            RecipeDetail(item) 
            // item1 = Apple Pie item
            // item2 = Pie Crust 
    }

    위의 그림처럼, NavigationStack의 동작 방식은

    •  path에 데이터만 담는 것이 아니라, 링크도 추가되고
    • pushed views에 view자체도 추가되기 때문에 NavigationStack이 전처럼 보여주는 기능으로도 가능하다.
    • 다만, path로 인해 좀 더 개발자 입장에서 쉽게 명시적으로 관리가 가능해진다.

    정리(NavigationView와의 차이)

    • NavigationView 만 사용했을 때는, 경로 추적이나 관리가 어려웠지만, path를 통해 경로를 명시적으로 관리할 수 있다.
    • NavigationStack으로 path에 넣으면서 관리하기 위해선, .navigationDestination(for: Item.self) 방식과 함께 작성해야한다.

     

    학습 참고

    [velog] NavigationStack 알아보기 | in WWDC22

    Apple Developer Documents | NavigationStack 

Designed by Tistory.