ListでのNavigationLinkとButtonを使った画面遷移

 List 内で NavigationLink で isActive を使用し、 Button で isActive を管理した時に isActiveが機能しなくなることがあったので対処法を記しておきます。

# Listを使用しないときの NavigationLink と Button の組み合わせ

 List を使用しない場合、 NavigationLink と Button を併用し isActive の Bool値を falase で固定すると、当然ですが画面遷移は起きません。

```:ContentView
 struct ContentView: View {
    @State var openDetailView = false
    
    var body: some View {
        ZStack {
            NavigationLink(
                destination: DetailView,
                isActive: $openDetailView,
                label: { EmptyView() }
            )
            Button(action: {
                //self.openDetailView = true
            }, label: {
                Text("画面遷移")
            })
        }
    }
    
    var DetailView: some View {
        Text("DetailView")
    }
}
```


## 上記のコードのListを追加する
では、上記のコードにListを追加してみます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409860/4cc8a666-55a9-f219-85de-17155b71b072.gif" width="250">

```:ContentView
struct ContentView: View {
    @State var openDetailView = false
    @State var selectedIndex = 0
    
    var body: some View {
        List(1..<11) { index in
            ZStack {
                NavigationLink(
                    destination: DetailView,
                    isActive: $openDetailView,
                    label: { EmptyView() }
                )
                Button(action: {
                    //self.openDetailView = true
                    selectedIndex = index
                }, label: {
                    Text("\(index)の画面遷移")
                })
            }
        }
    }
    
    var DetailView: some View {
        Text("\(selectedIndex)のDetailView")
    }
}
```

ここに List を追加すると isActive の値が false であるにも関わらず画面遷移が発生してしまします。

# Listを使用した NavigationLink と Button のベストプラクティス
 NavigationLink と ZStack を List の外に出すことで isActive を挙動通りに動かすことができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409860/58837eb2-30cf-1844-ef60-3091f0e150c2.gif" width="250">

```:ContentView
struct ContentView: View {
    @State var openDetailView = false
    @State var selectedIndex = 0
    
    var body: some View {
        ZStack {
            NavigationLink(
                destination: DetailView,
                isActive: $openDetailView,
                label: { EmptyView() }
            )
            
            List(1..<11) { index in
                Button(action: {
                    //self.openDetailView = true
                    selectedIndex = index
                }, label: {
                    HStack {
                        Text("\(index)の画面遷移")
                        Spacer()
                        Image(systemName: "chevron.right")
                    }
                })
            }
        }
    }
    
    var DetailView: some View {
        Text("\(selectedIndex)のDetailView")
    }
}
```

コメントアウトを外せば挙動通り、画面遷移が行われます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409860/ac908048-17cc-9133-0473-26d1a1d1b2e9.gif" width="250">


## NavigatoinView の定義
 NavigationView がないと NavigationLink は機能しないので、定義する必要があります。
ContentViewで使用しても良いですし、

```:ContentViewで使用する場合
var body: some View {
        ZStack {
            NavigationLink(
                destination: DetailView,
                isActive: $openDetailView,
                label: { EmptyView() }
            )
            Button(action: {
                //self.openDetailView = true
            }, label: {
                Text("画面遷移")
            })
        }
    }
```

{アプリ名}App.swift ファイルに指定してもOKです。

```:{アプリ名}Appの場合
@main
struct App: App {
  var body: some Scene {
    WindowGroup {
      NavigationView {
        ContentView()
      }
    }
  }
}
```