Open2

SwiftUI: ListのなかにnavigationDestinationを入れるな?

kabeyakabeya

今日、ふと気付いたんですが、Xcodeでデバッグ中に

Do not put a navigation destination modifier inside a "lazy” container, like List or LazyVStack. These containers create child views only when needed to render on screen. Add the navigation destination modifier outside these containers so that the navigation stack can always see the destination. There's a misplaced navigationDestination(isPresented:destination:) modifier presenting NewItemView. It will be ignored in a future release.

というメッセージが出るようになっています。

  • ListLazyVStackのように、「lazy」なコンテナの内側に、navigationDestinationモディファイアを置くな。
  • これらのコンテナは、画面に表示する必要がある際にしか、子ビューを生成しない。
  • navigationDestinationモディファイアは、NavigationStackが遷移先を常に見ることができるように、これらのコンテナの外に置け。
  • (お前のコードの)NewItemViewを表示するためのnavigationDestinationモディファイアは、(ここまで述べたように内側に)間違って置かれている。
  • このようなコードは、将来のリリースで無視されるようになる(=たぶん、見えてるときにしか遷移しなくなるってことを言ってるんでしょうね)。
NavigationStack {
    List {
        ForEach(self.items, id: \.self) { item in
            ItemView(item)
        }
        Button("新規アイテム追加") {
            self.showNewItemView.toggle()
        }
        .navigationDestination(isPresented: $showNewItemView) {  // 1) ←ここだと問題がある。
            NewItemView()
        }
    }
    //.navigationDestination(isPresented: $showNewItemView) { // 2) ←ここに置け。
    //    NewItemView()
    //}
}

こんな感じの話ですかね。

kabeyakabeya

ところで、いつからかデバッグログに
<decode: bad range for [%{public}s] got [offs:334 len:757 within:0]>
のような文言が出るようになりました。

で、どこから出てるのか全然分からなくて、苦労しながら絞り込んでいったんですが。

なんとなく、このnavigationDestinationモディファイアのメッセージが悪さをしてるんじゃないかという気がします。

navigationDestinationモディファイアのメッセージが出ないようにビュー階層(というかモディファイアの位置というか)を直したら出なくなりました。