SwiftUIの分厚い壁を感じたこと

# はじめに
SwiftUIで開発して最近一番ハマって未だ解決策がわかってない個人的問題を書いてみました。

これから実装する人のための人柱になれれば、
こんな方法で解決したという報告を望んだ記事になります。
# GestureとNavigationLink

どういうことなのかを説明していきます。
問題と感じているところがわかりやすいようサンプルコードを用意しました。


<img width="300" alt="スクリーンショット 2020-02-26 23.47.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/64b211b5-2820-cb8a-edf4-738ccc984a27.png">

縦方向のScrollViewの中にNavigationLinkで
括った数字(index)が表示されているCellが表示されてます。
Cellをタップするとindexの番号が表示されるだけの画面に遷移します。

コードは以下の通りです

```swift

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                VStack {
                    ForEach(0..<50, id: \.self) { index in
                        NavigationLink(destination: Text("tapped number \(index)")) {
                            ZStack(alignment: .center) {
                                Rectangle().frame(width: 375, height: 50)
                                Text("\(index)").foregroundColor(Color.black)
                            }
                        }
                    }
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```


期待している動作は以下gifの動作の通りです。
5のCellをタップしてスクロールをした際にタップ時に
5のCellにフォーカスがあたりScroll時にフォーカスが外れる感じです。
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/25442979-29b4-591f-d874-90cf4325fc80.gif">

## gestureが絡んでくる場合
仮にどれくらいスクロールしてるのかを判定して何か行いたい場合があったとします。
Scrollに`gesture`のmodifierをつけてonChangedで監視するコードを追加してみたとしましょう。

```swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            ScrollView(.vertical) {
                VStack {
                    ForEach(0..<50, id: \.self) { index in
                        NavigationLink(destination: Text("tapped number \(index)")) {
                            ZStack(alignment: .center) {
                                Rectangle().frame(width: 375, height: 50)
                                Text("\(index)").foregroundColor(Color.black)
                            }
                        }
                    }
                }
            }
            .gesture(DragGesture().onChanged { value in
                // スクロール量を知りたい
            })
        }
    }
}
```

動作確認です。
5のCellをタップしてスクロールをした際にタップ時には5のCellに
フォーカスがあたるのは`gesture`modifierを付ける前と動作は変わらないのですが
Scrollしてもフォーカスが外れないまま指を離すと画面遷移してしまいます。
<img width="300" alt="スクリーンショット 2020-02-26 23.47.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/1082a05b-255a-06af-1fc7-e705ad994c1d.gif">

gestureが絡むとNavigationLinkのフォーカスが
外れないままスクロールし離すタイミングで遷移されてしまうとUXがとても悪いと感じてます:sweat:

gestureをつけてもScroll時にタップしたCellのフォーカスが
外れるように試みたのですが今のところ解決策なしです:innocent:

# この問題について
[Apple Developer Forums](https://forums.developer.apple.com/thread/122083)
[SwiftUI: NavigationLink and ScrollView drag gesture colliding](https://stackoverflow.com/questions/58440469/swiftui-navigationlink-and-scrollview-drag-gesture-colliding)

ForumとStackOverflowから類似してると思われる記事を引っ張ってきました。
現状これといった解決策がないような気がします。
これはどう？というのあればぜひ共有いただきたいです:bow:

# さいごに
悔しいなぁ、SwiftUIで実装できることが一つ増えてもまたすぐ目の前に分厚い壁があるんだ:sob:

誰かの人柱になれていれば幸いです:japanese_goblin:

※UIKitで打開することは可能:smirk: