SwiftUIでListの中でNavigationLinkを複数使うとうまく動かない

SwiftUIでListの中でNavigationLinkを複数使うとうまく動かなかったのでメモです。

UIKitだと、UITableViewを使って1つのセルの中で複数のタップエリアを作って別々の画面に遷移させたいことがあると思います。 UITableViewCellaccessoryViewとかがまさにそんな感じの使い方かと思います。

SwiftUIでこれをしようとするとUITableViewの代わりにListを使って、遷移はNavigationLinkで行います。しかし、Listの中に複数のNavigationLinkをいれてしまうと、遷移の挙動がおかしくなります。

例えば以下のようなViewを作ると添付gifのような挙動になります。

struct ContentView: View {

    let data = [
        "Mavericks",
        "Yosemite",
        "El Capitan",
        "Sierra",
        "High Sierra",
        "Mojave",
        "Catalina"
    ]

    var body: some View {
        NavigationView {
            List(data, id: \.self) { data in
                VStack {
                    NavigationLink(destination: Text(data)) {
                        Text(data)
                    }
                    NavigationLink(destination: Text("Second navigation")) {
                        Text("additional navigation")
                    }
                }
            }
        }
    }
}

NavigationLink List

NavigationLinkを2つVStackで配置していても、タップエリアは全体で、遷移したあと戻ると自動で遷移されてしまいます。

この挙動を回避するには、今のところわたしが見つけた方法としては、Listの代わりにScrollViewを使うということです。

Listがデフォルトで提供してくれるスタイルは適用されなくなってしまいますが、ScrollViewを使うと実現できます。

struct ContentView: View {

    let data = [
        "Mavericks",
        "Yosemite",
        "El Capitan",
        "Sierra",
        "High Sierra",
        "Mojave",
        "Catalina"
    ]

    var body: some View {
        NavigationView {
            ScrollView(.vertical, showsIndicators: true) {
                ForEach(data, id: \.self) { data in
                    VStack {
                        NavigationLink(destination: Text(data)) {
                            Text(data)
                        }
                        NavigationLink(destination: Text("Second navigation")) {
                            Text("additional navigation")
                        }
                        Divider()
                    }
                }
            }
        }
    }
}

NavigationLink ScrollView

エンジニアリング SwiftUI List NavigationLink


関連記事