我以為的 NavigationLink

· 2min
Table of Contents

前言

在 UIKit 下, 使用 UINavigationController 跳轉頁面,
SwiftUI 相對應則是使用 NavigationStack + NavigationLink,
遇到了一個陷阱.

實作

一個 Item List, 點擊 row 之後跳轉到 Detail 頁面,
一般網路搜尋 NavigationLink 用法, 大部分都是教使用以下兩種方式

NavigationLink(title: StringProtocol, destination: () -> View)
NavigationLink(destination: () -> View, label: () -> View)

照著第二種方式, 使用 debug 時, 發現 Detail 在 Cell create 時, 也一併 create 了, 如圖

List {
    ForEach(viewModel.items, id: \.id) { item in
        NavigationLink {
            ItemDetail(item: item)
        } label: {
            Text("產品: \(item.id)")
        }
    }
}
image

正確的方式應該使用 NavigationLink(value:... + navigationDestination 才是正確方式

List {
    ForEach(viewModel.items, id: \.id) { item in
        NavigationLink(value: item) {
            Text("產品: \(item.id)")
        }
    }
}
.navigationDestination(for: Item.self) { item in
    ItemDetail(item: item)
}

也可使用 NavigationStack(path: $path)

參考

How to push a new view when a list row is tapped