ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Migrating to new navigation types
    SwiftUI/SwiftUI 애플 문서 한글화 2023. 6. 5. 14:48

    Article

    이 문서는 https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types 에 대한 한글화 문서입니다. 

    새로운 네비게이션 타입으로 전환 

    NavigationView를 Navigation Stack 이나 Navigation Split View 로 전환하여 앱의 탐색 동작을 향상시키기 

    Overview 

    앱의 최소 배포 타겟이 iOS 16, iPadOS 16, macOS 13, tvOS 16 또는 watchOS 9 이상인 경우 NavigationView를 NavigationStack 이나 NavigationSplitView로 교체하세요. 이를 사용하는 방법은 탐색(Navigation)을 한 열에서 수행하는지 아니면 여러 열에서 수행하는 지에 따라 달라집니다. 이러한 최신 컨테이너를 사용하면 뷰 프레젠테이션, 컨테이너 구성 및 프로그래밍 방식을 더 효율적으로 제어할 수 있습니다.

     

    한개의 열로 이루어진 네비게이션의 업데이트

    NavigationView를 사용하고 NavigationViewStyle을 stack으로 설정해 새 뷰를 스택에 푸시해 탐색하는 경우, NavigationStack을 사용해  전환합니다. 

    이제는 아래와 같이 코드를 작성하지 말고

    NavigationView { // This is deprecated.
        /* content */
    }
    .navigationViewStyle(.stack)

    대신 다음과 같이 NavigationStack을 사용합니다. 

    NavigationStack {
        /* content */
    }

    여러개로 이루어진 네비게이션의 업데이트 

    앱이 2열 또는 3열로 이루어진 NavigationView 같은 경우,  NavigationSplitView로 전환합니다.

    2열 네비게이션 뷰 대신 

    NavigationView { // This is deprecated.
        /* column 1 */
        /* column 2 */
    }

    init(sidebar:detail:) 이니셜라이저를 사용하여 명시적인 사이드바 및 세부 컨텐츠가 있는 네비게이션 스플릿 뷰를 만듭니다. 

    NavigationSplitView {
        /* column 1 */
    } detail: {
        /* column 2 */
    }

    마찬가지로 3열 네이게이션 뷰 대신

    NavigationView { // This is deprecated.
        /* column 1 */
        /* column 2 */
        /* column 3 */
    }

    init(sidebar:content:detail) 이니셜라이저를 사용하여 명시적인 사이드 바, 컨텐츠 및 세부 구성요소가 있는 네비게이션 스플릿 뷰를 만듭니다.

    NavigationSplitView {
        /* column 1 */
    } content: {
        /* column 2 */
    } detail: {
        /* column 3 */
    }

    열 내에 더 많은 탐색이 필요한 경우, 해당 열에 네비게이션 스택을 추가합니다. 이렇게 해서 각 열이 표시하는 컨텐츠를 보다 세밀하게 제어할 수 있습니다. NavigationSplitView를 사용하면 열의 가시성 및 너비를 지정할 수 있습니다.

    프로그래밍 방식의 네비게이션 업데이트

    isActive 매개변수가 있는 NavigationLink 이니셜라이저 중 하나를 사용하여 프로그래밍 방식으로 네비게이션을 사용한 경우 NavigationLink의 destination 으로 설정된 뷰가 스택으로 자동으로 이동합니다. 이를 네비게이션 링크의 init(value:label:) 이니셜라이저로 교체한 후 네비게이션 스택의 init(path:root:) 이니셜라이저를 사용하여 변경합니다.

    @State private var isShowingPurple = false
    @State private var isShowingPink = false
    @State private var isShowingOrange = false
    
    
    var body: some View {
        NavigationView { // This is deprecated.
            List {
                NavigationLink("Purple", isActive: $isShowingPurple) {
                    ColorDetail(color: .purple)
                }
                NavigationLink("Pink", isActive: $isShowingPink) {
                    ColorDetail(color: .pink)
                }
                NavigationLink("Orange", isActive: $isShowingOrange) {
                    ColorDetail(color: .orange)
                }
            }
        }
        .navigationViewStyle(.stack) 
    }

    코드의 다른 부분에서 상태 변수 중 하나를 true 설정하면 일치하는 태그가 있는 탐색 링크가 응답으로 활성화 됩니다. 

    위의 코드를 경로 입력을 받는 네비게이션 스택으로 다시 작성합니다. 

    @State private var path: [Color] = [] // Nothing on the stack by default.
    
    
    var body: some View {
        NavigationStack(path: $path) {
            List {
                NavigationLink("Purple", value: .purple)
                NavigationLink("Pink", value: .pink)
                NavigationLink("Orange", value: .orange)
            }
            .navigationDestination(for: Color.self) { color in
                ColorDetail(color: color)
            }
        }
    }

    이 버전은 naigationDestination(for:destination:) 뷰 한정자를 사용하여 해당 뷰에 사용하는 데이터를 분리합니다. 이는 path 배열이 스택의 모든 뷰를 나타낼 수 있습니다. 배열에 대한 변경 사항은 컨테이너가 표시하는 내용과 스택을 탐색할 때 접하는 내용에 영향을 줍니다.  NavigationPath를 사용하여 일반 데이터 컬렉션이 아닌 경로 정보를 저장하는 경우 훨씬 더 정교한 프로그래밍 방식의 탐색을 지원할 수 있습니다. 자세한 내용은 NavigationStack을 참조하세요.

     

    선택 방식의 네비게이션 업데이트

    List의 엘레멘트를 이용해 selection 매개 변수를 사용하는 NavigationLink 이니셜라이저 중 하나로 네비게이션을 프로래밍 하는 경우, selection을 List로 이동 시킬 수 있습니다. 예를 들어 selection 상태 변수에 대한 응답으로 활성화되는 링크가 있는 네비게이션 뷰가 있다고 가정하면 

    let colors: [Color] = [.purple, .pink, .orange]
    @State private var selection: Color? = nil // Nothing selected by default.
    
    
    var body: some View {
        NavigationView { // This is deprecated.
            List {
                ForEach(colors, id: \.self) { color in
                    NavigationLink(color.description, tag: color, selection: $selection) {
                        ColorDetail(color: color)
                    }
                }
            }
            Text("Pick a color")
        }
    }

    동일한 프로퍼티를 사용하여, body를 아래와 같이 다시 작성할 수 있습니다.

    var body: some View {
        NavigationSplitView {
            List(colors, id: \.self, selection: $selection) { color in
                NavigationLink(color.description, value: color)
            }
        } detail: {
            if let color = selection {
                ColorDetail(color: color)
            } else {
                Text("Pick a color")
            }
        }
    }

    코드의 다른 부분에서 selection 상태 변수를 변경하면 해당 색상에 대한 네비게이션 링크가 활성화되도록 리스트가 탐색 로직을 조정합니다. 마찬가지로 누군가 특정 색상과 연결된 네비게이션 링크를 선택하면 리스트는 코드의 다른 부분에서 읽을 수 있는 selectioin 값을 업데이트 합니다. (다른 곳에서 selection을 변경하면 리스트가 이를 알아차리고 Navigation 링크를 활성화 하고, 마찬가지로 네비게이션 링크를 활성화 하면 리스트가 selection 값을 변경해 다른 곳에서 알 수 있다는 말)

     

    See Also

    열에 뷰 표시 

    struct NavigationSplitView 

    2열 또는 3열에 뷰들을 표시하도록 하는 뷰로 앞에 있는 열의 선택이 뒤에 있는 열의 표시 방식을 제어합니다. 

     

    func navigationSplitViewStyle<S>(S) -> some View 

    뷰 안에 네비게이션 스플릿 뷰들의 스타일을 설정 

     

    func navigationSplitViewColumnWidth(CGFloat) -> some View 

    해당 뷰를 포함하는 열에 대해 고정되고, 선호하는 너비를 설정 

     

    func navigationSplitViewColumnWidth(min: CGFloat?, ideal: CGFloat, max: CGFloat?) -> some View

    해당 뷰를 포함하는 열애 대해 유연하고, 선호되는 너비를 설정 

     

    struct NavigationSplitViewVisibility

    스플릿 뷰에서 선행 열의 가시성 

     

    struct NavigationLink

    네비게이션의 보기를 제어하는 뷰

     

     

     

    댓글

Designed by Tistory.