네비게이션뷰는 보통 한카테고리에 들어와서 세부주제로 들어갈 떄 사용한다.
이와 반대로 탭바같은 경우는 대주제에 따라 달라진다.
그래서 일반적인 앱의 구조는 아래와 같은 구조로 진행된다.
- 탭바
- 1번 탭 : 네비게이션1
- 세부뷰 1-1
- 세부뷰 1-2
- 세부뷰 1-1
- 2번 탭 : 네비게이션2
- 세부뷰 2-1
- 세부뷰 2-2
- 세부뷰 2-1
- 1번 탭 : 네비게이션1
이런 View가 있다고 가정해보자.
import SwiftUI
struct ContentView: View {
var body: some View {
// 내부 컨텐츠
Text("설정")
}
}
- Step 1 : 여기에 내부 컨텐츠를 NavigationView { }로 감싸면 된다.
- Step 2 : 그리고 내부에 NavigationLink를 생성한다.
이 때, NavigationLink("이부분") 이부분에는 네비게이션 라벨에 표시할 문자열을 넣어준다.
Label부분과 destination부분이 있다. destination에는 이동 후 표시할 View가 들어간다.
NavigationLink의 생김새에 따라 여러가지 형태의 이니셜라이저가 존재한다.
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink("설정으로") { // label
Text("설정") // destination
}
}
}
}
이러면 Text자체가 버튼처럼 되면서 네비게이션이 적용된다.
이런식으로 여러 View들 사이에서 독자적으로 사용가능하다.
struct ContentView: View {
var body: some View {
NavigationView {
VStack {
Text("에어플레인 모드")
NavigationLink("설정으로") {
Text("설정")
}
}
}
}
}
이런 경우는 아래와 같이 생성된다.
struct ContentView: View {
var body: some View {
List {
Text("스크린타임")
Text("에어플레인 모드")
}
}
}
만약 화면에 이렇게 리스트로 적용이 되어있는 경우,
여기에 navigationView를 적용하면 리스트에 자동으로 disclosure indicator가 생성된다.
struct ContentView: View {
var body: some View {
NavigationView {
List {
NavigationLink("스크린타임") {
Text("스크린타임 페이지")
}
Text("에어플레인 모드")
}
}
}
}
NavigationLink()의 인자로 문자열이 들어가는 경우에는 앞선 형태로 가능하지만,
상황에 따라 Image나 혹은 리스트내부의 View 자체를 클릭했을 때, 네비게이션이 실행되는 경우도 있다.
- Image로 이동하기
struct ContentView: View {
var body: some View {
Image(systemName: "airplane")
.resizable()
.frame(width: 200,
height: 200)
}
}
이런 이미지가 하나 있는데, 이 자체를 네비게이션 링크로 사용하려면 아래와 같이 사용한다.
//기존의 문자열만 가지고 사용하는 경우
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink("스크린타임") { // label
Text("스크린타임 페이지") // destination
}
}
}
}
// 문자열 이외의 label
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink {
Text("에어플레인 모드") // destination
} label: { // label
Image(systemName: "airplane")
.resizable()
.frame(width: 200,
height: 200)
}
}
}
}
이렇게 되면 아래와 같이 된다.
이번에는 List 내부에 세팅을 해보자. 이런 모양이 있다.
struct ContentView: View {
var body: some View {
NavigationView {
List {
HStack {
Image(systemName: "wifi")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20,
height: 20)
.padding(.all, 5)
.background(.blue)
.foregroundStyle(.white)
.cornerRadius(6)
// 라벨로 만들고 싶은 부분
HStack {
Text("Wi-Fi")
Spacer()
Text("SK_WKF4DJ7KD")
.foregroundStyle(.gray)
}
}
Text("설정")
Text("개인용 핫스팟")
.navigationTitle(Text("설정"))
}
}
}
}
여기에 라벨로 만들고 싶은 부분을 통채로 NavigationLink의 label View 부분에 넣어준다.
struct ContentView: View {
var body: some View {
NavigationView {
List {
HStack {
Image(systemName: "wifi")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20,
height: 20)
.padding(.all, 5)
.background(.blue)
.foregroundStyle(.white)
.cornerRadius(6)
NavigationLink {
Text("Wi-Fi") // destination
} label: {
HStack {
Text("Wi-Fi")
Spacer()
Text("SK_WKF4DJ7KD")
.foregroundStyle(.gray)
}
}
}
Text("설정")
Text("개인용 핫스팟")
.navigationTitle(Text("설정"))
}
}
}
}
그러면 아래와 같이 세팅된다.
이건 바로 위 예제 처럼 NavigationView 클로저 안에서
.navigationTitle("문자열")
형태로 입력하면 된다.
- 231127: 초안작성