
NavigationView
는 SwiftUI
의 가장 중요한 구성 요소 중 하나입니다. 화면을 쉽게 Push
와 Pop
할 수 있으며, 사용자에게 명확하고 계층적인 방식으로 정보를 제공할 수 있습니다
NavigationView
NavigationView
를 사용하려면 다음과 같이 항목을 감싸야합니다.
struct ContentView: View { var body: some View { NavigationView { Text("Hello, World!") } } }
NavigationView
는 최상위에 위치해야 하지만, TabView
내에서 사용하는 경우에는 NavigationView
가 TabView
내에 있어야 합니다.
// 옳은 방법 NavigationView { Text("Hello, World!") .navigationBarTitle("Navigation") } //잘못된 방법 NavigationView { Text("Hello, World!") } .navigationBarTitle("Navigation")
NavigationView
내에서 navigationBarTitle()
를 사용할 수 있으며, 뷰 바깥쪽에서 사용하지 않아도 됩니다. 또한 displayMode parameter
를 사용하여 커스터마징을 할 수 있습니다.
displayMode
.large 옵션은 내비게이션 스택의 최상위 보기에 유용한 큰 제목을 표시합니다.
.inline
옵션은 내비게이션 스택의 2 차, 3 차 또는 후속 보기에 유용한 작은 제목을 표시합니다.
.automatic
옵션은 기본값이며 이전에 사용한 View를 사용합니다.
.navigationBarTitle("Navigation") //기본값에 .automatic 가 포함 되어 있다.
.navigationBarTitle("Navigation", displayMode: .inline)
NavigationLink
NavigationLink(destination: Text("String"))
SwiftUI
의 NavigationView
는 View
의 맨 위에 NavigationBar
를 표시하지만 다른 작업도 수행합니다.
View
를 view stack
에 푸시할 수 있습니다. 이것은 iOS view
의 가장 기본적인 형태입니다. 예를 들어 WIFI
를 탭 하면 설정으로 들어가져서 WIFI
목록을 볼 수 있거나, 연락처에서 이름을 탭 하면 메시지를 보내는 것과 같습니다.
TextView
를 NavigationView
로 래핑
하고 제목을 지정하면 다음과 같은 결과가 나타납니다.
struct ContentView: View { var body: some View { NavigationView { VStack { Text("Hello World") } .navigationBarTitle("SwiftUI") } } }
→ 기본적인 NavigationView
형태.
화면을 보면 텍스트의 Hello Wolrd
에 아무런 변화가 없이 단지 텍스트로 보이죠? 이제 헬로월드를 클릭하면 새로운 탭으로 이동하는 코드를 작성해 봅시다!
struct ContentView: View { var body: some View { NavigationView { VStack { NavigationLink(destination: Text("Detail View")) { Text("Hello World") } } .navigationBarTitle("SwiftUI") } } }
→ 이제 화면에 Hello World
부분을 탭할 수 있게 바뀌고 그것을 누르면 Detail View
로 이동할 수 있습니다. 하지만 여기서 의문점이 있습니다.
Sheet()
와 NavigationLink
의 차이점이 무엇일까?
NavigationLink
는 topic
을 더 자세히 살펴보는 것처럼 사용자가 선택한 것에 대한 세부 정보를 보여 줍니다.
sheet()
는 설정 또는 작성 창과 같은 관련 없는 내용을 표시하는 데 사용됩니다.
List 와 NavigationLink
List
에서 row in
하여 Navigation
내 destination: Text
에 row
를 추가해주고, Text
에 도 row
를 할당해줍니다.
NavigationView { List(0..<100) { row in NavigationLink(destination: Text("Detail \(row)")) { Text("Row \(row)") } } .navigationBarTitle("SwiftUI") }

View를 추가하여 NavigationLink에 연동
만약 동전의 앞과 뒤 중에 골라야 하는 버튼이 있고, 그 버튼을 누르면 " 를 선택하셨습니다
" 와 같은 텍스트를 보여주고 싶으면
아래와 같이 ContentView
바깥에 또 다른 View
를 생성해 주면 됩니다.
struct ResultView: View { var choice: String var body: some View { Text("\(choice)을 선택하셨습니다. ") } }
이제 ContentView
에 NavigationView
와 Text
, NavigationLink
등을 추가해줍니다.
import SwiftUI struct ResultView: View { var choice: String var body: some View { Text("\(choice)을 선택하셨습니다. ") } } struct ContentView: View { var body: some View { NavigationView { VStack(spacing: 30) { Text("당신은 동전을 던질것입니다\n앞면 과 뒷면 중에 하나를 선택해 주세요.") .multilineTextAlignment(.center) NavigationLink(destination: ResultView(choice: "앞면")) { Text("앞면을 선택하셨습니다.") } NavigationLink(destination: ResultView(choice: "뒷면")) { Text("뒷면을 선택하셨습니다.") } } .navigationBarTitle("Navigation") } } }
Image 와 NavigationLink
아래 코드와 같이 NavigationLink
내에서 Image
를 넣어주면 자동으로 텍스트와 모든 것을 파란색으로 설정하게 됩니다.
이것은 때때로 유용할 수 도 있지만, 그렇지 않은 경우가 더 많이 있습니다.
NavigationView { NavigationLink(destination: Text("Second View")) { Image("원하는 사진") } .navigationBarTitle("Navigation") }
만약 사진을 정상적으로 보여주고 싶다면 .renderingMode(.original)
를 Image
밑에 추가해 주면 됩니다.
NavigationView { NavigationLink(destination: Text("Second View")) { Image("원하는 사진") .renderingMode(.original) } .navigationBarTitle("Navigation") }
이것의 대안으로는 PlainButtonStyle()
과 함께 buttonStyle()
수정자를 사용할 수 있습니다.
NavigationView { NavigationLink(destination: Text("Second View")) { Image("원하는 사진") } .buttonStyle(PlainButtonStyle()) .navigationTitle("Navigation") }
혹은 button
으로 만들어 줄 수 있겠죠.
NavigationView { Button { // your action here } label: { Image("card") .resizable() .scaledToFit() } .buttonStyle(PlainButtonStyle()) .navigationTitle("Navigation") }
Environment presentationMode
NavigationLink view
에서 Back
버튼을 hidden
으로 해놓고 따로 버튼을 만들어서 그 버튼을 누르면 메인화면으로 돌아갈 수 있도록 만들어 줄 수도 있습니다. 이것을 사용하기 위해서는 Environment
의 preseontationMode
를 사용 하면 됩니다.
import SwiftUI struct ContentView: View { var body: some View { NavigationView { ScrollView(.vertical, showsIndicators: false) { Text("some") Text("some") Text("some") } .navigationBarTitle("네비게이션") .navigationBarItems( trailing: NavigationLink( destination: secondView(), label: { Image(systemName: "person.fill") .foregroundColor(.red) }) ) } } } struct secondView: View { @Environment(\.presentationMode) var presentationMode var body: some View { ZStack(alignment: .topLeading) { Color.yellow.ignoresSafeArea() .navigationBarBackButtonHidden(true) .navigationBarHidden(true) Button(action: { presentationMode.wrappedValue.dismiss() }, label: { Image(systemName: "xmark") .imageScale(.large) .padding() }) .accentColor(.white) } } }

NavigationBarItems / NavigationBarTitle
위에서 나왔던 navigationBarTitle
의 종류에 대해서 먼저 알아보겠습니다.
NavigationView { Text("서근 개발블로그") .navigationBarTitle("스위프트UI", displayMode: .inline) }

automatic
/ inline
/ large
3가지가 있고, 기본값이 automatic
인거 같죠? 일단 inline
을 먼저 사용해서 화면을 구성해보면,

여기에 NavigationBarItems
을 추가해 봅시다.

leading
/ trailing
이 있네요. 이제 navigationBarTitle
에 아이템을 추가해서 오른쪽, 왼쪽 버튼을 만들어볼게요.
NavigationView { Text("서근 개발블로그") .navigationBarTitle("스위프트UI", displayMode: .inline) .navigationBarItems(leading: Button("왼쪽") { /*code*/ } ,trailing: Button("오른쪽") { /*code*/ } )

왼쪽에 버튼을 두 개 추가하고 싶을 땐?
NavigationView { Text("서근 개발블로그") .navigationBarTitle("스위프트UI", displayMode: .inline) .navigationBarItems(leading: HStack { Button("서근") { /*code*/ } Button("블로그") { /*code*/ } },trailing: HStack { Button("구독") { /*code*/ } Button("좋아요") { /*code*/ } } ) }

뭐.. 버튼이 기본적이지만, 텍스트를 주고 싶다면 가능은 합니다 :)
NavigationView { Text("서근 개발블로그") .navigationBarTitle("스위프트UI", displayMode: .inline) .navigationBarItems(leading: Text("서근"), trailing: Text("블로그") ) }

SF Symbols
를 .navigationBarItems
에 추가해보도록 하겠습니다.
Image
로 불러와주고 심볼 아이템을 resizable()
해주고 frame()
으로 크기를 조절해 주겠습니다.
struct DetailView: View { var body: some View { Text("서근 개발 블로그") } } struct ContentView: View { var body: some View { NavigationView { Text("사이트") .navigationBarTitle(Text("홈")) .navigationBarItems(trailing: NavigationLink(destination: DetailView()){ Image(systemName: "paperplane.circle.fill").resizable() .frame(width: 30, height: 30, alignment: .trailing) } ) } } }

심볼 사이즈를 frame()
으로 지정해줄 수 도 있지만 .font(.system(size: CGFloat))
으로도 가능합니다.
NavigationView { Text("사이트") .navigationBarTitle(Text("홈")) .navigationBarItems(trailing: NavigationLink(destination: DetailView()){ Image(systemName: "paperplane.circle.fill").font(.system(size: 30)) } ) }
Hidden
navigationBarHidden
이밖에도 필요에 따라 NavigationBar
또는 back
버튼을 숨길 수 있습니다.
NavigationView { HStack { Image(systemName: "person.fill") Text("서근 개발 블로그") .navigationTitle("NavigationBarHidden") .navigationBarHidden(true) } }

navigationBackButtonHidden
마찬가지로 back
버튼을 숨기려면 원하는 뷰 뒤에 코드를 추가해줘야 합니다.
NavigationView { HStack { Image(systemName: "person.fill") Text("서근 개발 블로그") .navigationTitle("NavigationBarHidden") .navigationBarItems(trailing: NavigationLink(destination: Text("안녕하세요").navigationBarBackButtonHidden(true)) { Image(systemName: "star.fill").font(.title) } ) } }
navigationBarBackButtonHidden 사용 주의사항
destination
으로 가져온 뷰 바로 뒤에 navigationBarBackButton
을 추가해줘야 합니다.
읽어주셔서 감사합니다🤟
'SWIFTUI > View layout' 카테고리의 다른 글
SwiftUI : Stepper (onIncrement / onDecrement) (0) | 2021.01.25 |
---|---|
SwiftUI : ForEach (0) | 2021.01.24 |
SwiftUI : Overlay / Background / Alignment (0) | 2021.01.22 |
SwiftUI : HStack / Spacer / minLength / Frame (2) | 2021.01.22 |
SwiftUI : View layout (HStack / VStack / ZStack) (0) | 2021.01.22 |