[SwiftUI] Navigation

2024. 9. 24. 13:48·Dev/SwiftUI

 

 

 

참여 중인 회사 프로젝트에서 UIKit과 SwiftUI 프레임워크를 함께 사용하고 있다.

 

탭바와 같은 화면 전환은 UIKit을 사용하고 있지만 사실 SwiftUI의 내비게이션 기능을 제대로 사용해 본 경험이 없었다. 대신 틈나는 대로 직관로그 UI를 SwiftUI로 리팩토링하고 있어서 겸사겸사 화면 전환 관련 로직을 다루기 전 사전 학습으로 SwiftUI의 내비게이션을 조금 뜯어보기로 했다.

 

참고로, 이 글에서 다룰 Navigation은 iOS 16 이상을 기준으로 작성했다.

 

iOS 16 이전엔 NavigationView를 사용했지만, iOS 16에선 해당 API가 deprecated가 되었다.

이 글에선 NavigationView에 대한 내용은 다루지 않을 예정이다.

 

 

 

 


 

 

 

애플 공식 문서에 따르면, iOS 16 이전과 이후의 내비게이션 형식은 다음과 같이 변화했다.

 

iOS 16 이전과 이후의 형식 변화 from 애플공식문서

 

 

 

 

현재 SwiftUI 내에서 내비게이션으로 화면 전환을 하는 방식은 크게 네 가지로 구분할 수 있다.

  1. NavigationStack + NavigationLink
  2. NavigationStack + NavigationDestination
  3. NavigationStack + NavigationLink + NavigationDestination
  4. NavigationStack + NavigationPath + NavigationDestination

 

정의

NavigationStack, NavigationLink, NavigationDestination

 

 

NavigationStack

: A view that displays a root view and enables you to present additional views over the root view. 

 

애플 공식 문서에 따르면, NavigationStack은 루트 뷰(root view)를 표시하고 그 위에 추가 뷰들을 쌓을 수 있도록 하는 뷰다. 이름 그대로 "Stack"처럼 루트 뷰를 가장 아래에 두고 내비게이션을 기반으로 뷰들이 차례로 쌓이는 구조를 갖는다.

 

 

NavigationLink 

: A view that controls a navigation presentation. 

 

내비게이션 전환을 제어하는 뷰다. 클릭 또는 탭과 같은 사용자 상호작용에 의해 특정 목적지 뷰로 이동시키는 역할을 한다.

 

 

NavigationDestination 

: Associates a destination view with a presented data type for use within a navigation stack. 

 

NavigationStack 내에서 사용하기 위해 특정 데이터 타입과 연결된 목적지 뷰를 지정한다.

여기서 '데이터'는 전환될 뷰의 타입과 일치하는 데이터를 의미한다.

 

 

NavigationStack과 NavigationLink 

NavigationStack은 루트 뷰를 기준으로 뷰 스택을 관리하고, NavigationLink는 그 뷰 스택에 새로운 뷰를 추가하는 역할을 수행한다. 따라서 NavigationStack과 NavigationLink는 세트라고 볼 수 있다.

 

정리하자면 NavigationStack 안에 NavigationLink를 구현해서,

 

 1. 뷰 스택을 만든다 (NavigationStack) 

2. 뷰를 추가한다. (NavigaitonLink) 

 

위의 방식을 통하여 SwiftUI 내에서 네비게이션을 구현한다.

 

 

 


 

 

 

 

 

위 개념을 활용하여 기본적인 내비게이션 화면 전환 예제 코드를 구현해 보았다.

 

예시 1: NavigationStack과 NavigationLink의 기본 사용법

 

 


활용 api:

  •  https://developer.apple.com/documentation/swiftui/navigationlink/init(_:destination:)-7d6im
 

init(_:destination:) | Apple Developer Documentation

Creates a navigation link that presents a destination view, with a text label that the link generates from a localized string key.

developer.apple.com

 

 

가정: 

 

  • 루트 뷰는 NaviBaseView이며, 이 내비게이션 스택 위에 NaviYellowView와 NaviOrangeView를 각각 쌓아 내비게이션으로 화면 전환을 구현한다.
  • 전환 방식은 RootView → ChildView로 Push/Pop 형태이다.

 

 

코드:

import SwiftUI

struct NaviBaseView: View {
  
  var body: some View {
    
    NavigationStack {
      NavigationLink("YellowView") {
        NaviYellowView()
      }
      
      NavigationLink("OrangeView") {
        NaviOrangeView()
      }
    }
    
  } // body
} // view

 

 

 

  • NavigationStack 안에 NavigationLink를 사용하여 전환할 뷰들을 추가했다.
  • NaviBaseView가 루트 뷰이므로, 시뮬레이션 영상에서 확인할 수 있듯이 이 뷰를 기준으로 뷰가 쌓여서 전환된다.
  • NavigationLink("value")의 value 부분은 버튼과 같은 역할을 한다.

 

 

 

예제 2: 커스텀 버튼과 navigationDestination을 활용한 화면 전환

 

 

 

 

활용 api:

https://developer.apple.com/documentation/swiftui/view/navigationdestination(for:destination:)

 

navigationDestination(for:destination:) | Apple Developer Documentation

Associates a destination view with a presented data type for use within a navigation stack.

developer.apple.com

 

가정: 

  • NavigationLink의 텍스트가 아닌 커스텀 버튼을 눌러 하위 뷰로 화면 전환을 구현한다.

 

코드:

import SwiftUI

struct NaviBaseView: View {
  
  // 1. 버튼 상태값
  @State private var isButtonTapped: Bool = false
  
  var body: some View {

   NavigationStack {
   
   // 2. 버튼 추가
      Button(action: {
        isButtonTapped = true
      }, label: {
        Text("Button")
          .frame(width: 100, height: 48)
          .background(.green)
      })
      
    // 3. 상태값 바인딩 + 이동할 뷰 추가
      .navigationDestination(isPresented: $isButtonTapped) {
        NaviYellowView()
      }
    }
    
  } // body
} // view

 

  • 버튼의 상태 값(isButtonTapped)을 트리거로 사용하여 내비게이션 화면 전환을 구현하는 기본 코드다.

 

 

 


 

 

 

References

 

https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types#Update-single-column-navigation

 

Migrating to new navigation types | Apple Developer Documentation

Improve navigation behavior in your app by replacing navigation views with navigation stacks and navigation split views.

developer.apple.com

 

https://medium.com/@hagjini0/swiftui-navigationlink-navigationstack-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0-8a22eaddfddc

 

SwiftUI: NavigationLink, NavigationStack 알아보기

우리가 사용하는 앱은 대부분 1개 이상의 화면을 가진다. 이 화면들 사이를 자유롭게 이동하기 위해서는 Tab, modal 또는 Navigation 등을 사용할 수 있다.

medium.com

 

https://zeddios.tistory.com/1376

 

[SwiftUI] NavigationView ➡️ NavigationStack

안녕하세요 :) Zedd입니다. @available(iOS, introduced: 13.0, deprecated: 100000.0, message: "use NavigationStack or NavigationSplitView instead") public struct NavigationView : View where Content : View { ... } WWDC22에서 NavigationView가 depreca

zeddios.tistory.com

 

https://www.celinemoon.com/blog/navigationstack-and-navigationpath/

 

SwiftUI NavigationStack과 NavigationPath

SwiftUI에서 NavigationStack 사용하는 다양한 방법

www.celinemoon.com

 

저작자표시 (새창열림)

'Dev > SwiftUI' 카테고리의 다른 글

[SwiftUI] LifeCycle  (1) 2024.10.14
[SwiftUI] ObservableObject, ObservedObject, Published  (5) 2024.10.07
[SwiftUI] scrollTargetLayout과 ScrollTargetBehavior  (0) 2024.08.16
[SwiftUI] Property Wrapper 총정리  (0) 2024.07.26
[SwiftUI] Frame  (0) 2024.07.22
'Dev/SwiftUI' 카테고리의 다른 글
  • [SwiftUI] LifeCycle
  • [SwiftUI] ObservableObject, ObservedObject, Published
  • [SwiftUI] scrollTargetLayout과 ScrollTargetBehavior
  • [SwiftUI] Property Wrapper 총정리
Callie_
Callie_
  • Callie_
    CalliOS
    Callie_
  • 전체
    오늘
    어제
    • 분류 전체보기
      • APPLE
      • Dev
        • Swift
        • UIKit
        • SwiftUI
        • Issue
        • 구현
      • Design
        • HIG
      • CS
      • 직관로그 (출시앱)
        • 업데이트
      • 🌱 SeSAC iOS 3기
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    DidEndOnExit
    Entry Point
    SwiftUI
    생명주기
    Info탭
    modalPresentStyle
    cornerradius
    TableViewCell
    Enum
    네트워크통신
    화면전환
    layer.shadow
    .fullScreen
    IBAction
    clipsToBound
    keyboard
    TapGestureRecognizer
    .OverFullScreen
    SeSAC
    Button
    addTarget
    stroyboard
    후기
    Swift
    cs
    tag
    ios
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Callie_
[SwiftUI] Navigation
상단으로

티스토리툴바