LoginSignup
17
6

More than 3 years have passed since last update.

【SwiftUI】NavigationLinkは即評価される

Last updated at Posted at 2020-01-12

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.comb.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における落とし穴とその対策を紹介しました。

17
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
6