
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 |





