【SwiftUI】Listと一緒に使ったNavigationlinkが思っていない動きをする。

以下のようなコードで、画面遷移を実現したんだけど・・・

import SwiftUI

struct ContentView: View {
    let strings = ["first","second","third"]
    @State private var isShowMain: Bool = false
    
    var body: some View {
        NavigationView{
            List{
                ForEach(strings, id: \.self){ onestring in
                    NavigationLink(destination: NextView(selected: onestring,isShowMain: $isShowMain), isActive: $isShowMain
                    ){
                        Text(onestring)
                    }
                    
                }
            }
        }
    }
}


struct NextView:View{
    let selected: String
    @Binding var isShowMain:Bool
    
    var body: some View{
        VStack{
            Text(selected)
            
            Button(action: {
                isShowMain.toggle()
            }, label: {
                Text("戻る")
            })
        }
    }
    
}

gifのように選択したところと全く違うところが選択されてしまう!!

(ちゃんとgif再生されているのか?)

/img/navigation_trouble_2022_6_20.gif
問題発生

問題解決

画面遷移先で、ひだり上の戻るボタンではなく自分で作成したボタンで元の画面に戻れるようにしたくて、isActiveを使ったのが問題だった。

どうやら、NavigationLinkのViewをクリックすると、画面が遷移して、遷移すると、isActiveの値もtrueになるみたい。

おそらくこれが悪さをしているように感じた。

foreachでnavigationLinkを作りまくっていて、全部引数にisActiveを持っている。 で、一つのnavigationLinkをクリックすると、他のNavigationLinkのisActiveの値も、trueに変わる。そうすると、isActiveがtrueなので、他のNavigationLinkもdestinationを表示しようと頑張って、意図していない(タップしていない)箇所のNavigationLinkが呼び出されると思う。

多分そうだと思う!!!

isActiveを使うときはそれに注意が必要ね・・・

以下のようなコードにしたら解決しました!

import SwiftUI

struct ContentView: View {
    let strings = ["first","second","third"]

    var body: some View {
        NavigationView{
            List{
                ForEach(strings, id: \.self){ onestring in
                    NavigationLink(destination: NextView(selected: onestring)
                    ){
                        Text(onestring)
                    }
                    
                }
            }
        }
    }
}


struct NextView:View{
    let selected: String
    @Environment(\.dismiss) var dismiss

    var body: some View{
        VStack{
            Text(selected)
            
            Button(action: {
                dismiss()
            }, label: {
                Text("戻る")
            })
        }
    }
    
}

/img/navigation_resolve_2022_6_20.gif

別の方法で画面遷移を行うようにした!

参考にしました

SwiftUI の NavigationLink(destination:,isActive:) を活用する

【SwiftUI】画面を閉じるdismissとisPresentedについて

. . . .

解決できてよかった・・・