SwiftUIのNavigationLink
はすぐに評価されてしまうので、場合によっては遅延評価されるように対処が必要という話です。
現象
たとえばこんなコードがあったとします。
サンプルコード
struct ContentView: View {
var urls = ["a.com", "b.com"]
var body: some View {
HStack {
List(urls) { url in
NavigationLink(destination: BrowserContentView(url: url)) {
Text("Next Page")
}
}
}
}
}
ここで、BrowserContentView
はすぐに初期化されてしまいます。例えば、この中でurl
で指定されているWebページを読み込んでいたとすると、a.com
もb.com
も読み込まれてしまいます。一覧画面を作るときに、その遷移先まで初期化してしまうのではリソースがもったいないですね。
対策方法
このページにあるように、遅延評価をできるstruct
を作ってそれを差し込みます。
遅延評価用のstruct
struct LazyView<Content: View>: View {
let build: () -> Content
init(_ build: @autoclosure @escaping () -> Content) {
self.build = build
}
var body: Content {
build()
}
}
修正後のコード
struct ContentView: View {
var urls = ["a.com", "b.com"]
var body: some View {
HStack {
List(urls) { url in
NavigationLink(destination: LazyView(BrowserContentView(url: url))) {
Text("Next Page")
}
}
}
}
}
これで遅延評価されるようになりました。この方法ならリンクが押されたときに該当のWebページが読み込まれるようになります。
まとめ
NavigationLink
における落とし穴とその対策を紹介しました。