https://developer.apple.com/documentation/swiftui/navigationview
NavigationView가 deprecated 된다고 합니다 NavigationStack의 Minimum은 iOS 16+
struct TestNavigationStack: View {
var body: some View {
NavigationView {
List(0...5, id: \.self) { index in
NavigationLink {
FirstDestinationView(viewModel: FirstDestinationViewModel())
} label: {
Text("\(index)번째 버튼")
.font(.largeTitle)
.bold()
}
}.navigationTitle("네비게이션 스택 연습")
}
}
}
@MainActor
class FirstDestinationViewModel: ObservableObject {
@Published var image: UIImage? = nil
init() {
downloadImage()
}
func downloadImage() {
Task {
let url = URL(string: "https://picsum.photos/200")!
let (data, _) = try await URLSession.shared.data(from: url)
if let image = UIImage(data: data) {
self.image = image
print("이미지가 다운로드 되었습니다")
}
}
}
}
struct FirstDestinationView: View {
@StateObject private var viewModel: FirstDestinationViewModel
init(viewModel: FirstDestinationViewModel) {
print("목적지가 되는 뷰가 생성 되었습니다!")
_viewModel = StateObject(wrappedValue: viewModel)
}
var body: some View {
VStack {
if let image = viewModel.image {
Image(uiImage: image)
.resizable()
.scaledToFit()
.frame(width: 200, height: 200)
}
Text("목적지가 되는 뷰")
}
}
}프린트문을 찍어보면~!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
오잇...!
다 다운되고 있네요
기존 NavigationView는 Destination이 되는 View도 진입하기 전에 미리 init �해버린다!
struct TestNavigationStack: View {
var body: some View {
NavigationStack {
List(0...5, id: \.self) { index in
NavigationLink(value: index) {
Text("\(index) 버튼")
.font(.largeTitle)
.bold()
}
}
.navigationTitle("네비게이션 스택 연습")
.navigationDestination(for: Int.self) { value in
FirstDestinationView(viewModel: FirstDestinationViewModel())
}
}
}
}목적지가 되는 뷰가 생성 되었습니다!
목적지가 되는 뷰가 생성 되었습니다!
이미지가 다운로드 되었습니다
이미지가 다운로드 되었습니다
오케이! 진입을 해야 init이 되네요 이제!
(그럼에도 두번이 찍히는 건..) https://developer.apple.com/forums/thread/718281
이번엔 코드로 Navigation을 이동시키는 걸 해보겠습니다.
struct TestNavigationStack: View {
let appleProducts = ["Mac", "Macbook", "iPhone", "iPad"]
@State private var stackPath: [String] = []
var body: some View {
NavigationStack(path: $stackPath) {
List(appleProducts, id: \.self) { product in
NavigationLink(value: product) {
Text(product)
}
}
.navigationDestination(for: String.self) { product in
Text("\(product) has Clicked!")
}
Button {
stackPath.append("Mac")
} label: {
Text("네비게이션 프슝")
.font(.largeTitle)
.bold()
}
}
}
}NavigationPath 타입을 사용해주면 됩니다!
struct TestNavigationStack: View {
let appleProducts = ["Mac", "Macbook", "iPhone", "iPad"]
@State private var stackPath: NavigationPath = .init()
var body: some View {
NavigationStack(path: $stackPath) {
List(appleProducts, id: \.self) { product in
Button {
stackPath.append(product)
} label: {
Text(product)
.font(.largeTitle)
.bold()
}
Button {
stackPath.append(1)
} label: {
Text("For Int")
}
}
.navigationDestination(for: String.self) { product in
Text("\(product) has Clicked!")
}
.navigationDestination(for: Int.self) { int in
Text("\(int)")
}
}
}
}좀 더 깊숙히 들어가볼까요!
struct TestNavigationStack: View {
let appleProducts = ["Mac", "Macbook", "iPhone", "iPad"]
@State private var stackPath: NavigationPath = .init()
var body: some View {
NavigationStack(path: $stackPath) {
List(appleProducts, id: \.self) { product in
Button {
stackPath.append(product)
} label: {
Text(product)
.font(.largeTitle)
.bold()
}
Button {
stackPath.append(1)
} label: {
Text("For Int")
}
}
.navigationDestination(for: String.self) { product in
AppleProductView(product: product, path: $stackPath)
}
.navigationDestination(for: Int.self) { int in
Text("\(int)")
}
}
}
}
struct AppleProductView: View {
let product: String
@Binding var path: NavigationPath
var body: some View {
VStack(spacing: 20) {
Text(product)
.font(.largeTitle)
.onTapGesture {
path.append("세번째 데스티네이션..!!")
}
Text("모두 없애버리기")
.onTapGesture {
path = .init()
}
}
}
}NavigationStack에 관련된 기본은 이 정도가 될 것 같아요
다음 영상들에서 해볼 건 만약에 같은 타입에 같은 모델일 때 도착지점이 다르게 하고 싶다면 어떻게 코드를 구성해야할지에 대해서! NavigationPath를 지금처럼 View가 들고 있지 않고 다른 객체가 들고 있게 하는 것도 해보고, 또 NavigationStack과 TabView를 같이 사용할 때는 어떻게 해야할지 한번 고민해보면 좋을 것 같아요