結論:PhraseBoard v1.2.1では、定型文セル上からスクロールしにくい問題が報告されました。開発当時、iPad Pro 12.9インチ(第2世代)のiOS 17.2 Simulatorで再現し、セルのコピー用LongPressGestureだけを無効にした診断版では、セル上からスクロールできたと報告されています。この結果を踏まえ、v1.2.2ではiOS 17にMenuとprimaryActionを採用し、iOS 18以降は従来の長押し処理を維持しました。これはPhraseBoardの実装と検証環境で確認した事例で、すべてのiPadOS 17環境に当てはまると示すものではありません。

この記事では、実際の問い合わせから再現、A/Bテスト、修正後の確認までを記録します。コードの変更と手動操作の結果を分け、確認できた範囲を示します。

発生した不具合:余白では動くが、セル上では選択される

2026年10月3日、PhraseBoardの利用者から「カテゴリ内の下に隠れた文章を選択できない」と問い合わせがありました。追加の説明では、余白を指でドラッグすると一覧が動く一方、定型文セル上からスクロールしようとすると、意図しない定型文が選択されるとのことでした。

利用者からの申告
iPad Pro(第2世代、12.9インチ)/横向き/ハードウェアキーボード接続/複数行の定型文2件。OSは後の返信でiPadOS 17.7.11と申告されました。端末から直接取得した値ではなく、利用者からの申告です。

つまり、ScrollView全体が動かなかったわけではありません。余白からはスクロールできても、セル上で始めたドラッグが定型文の選択になってしまい、一覧を操作しにくい状態でした。

開発側で不具合を再現

開発者は、App Store配信中のPhraseBoard v1.2.1をiPad Pro 12.9インチ(第2世代)・iOS 17.2 Simulator・横向きで動かし、スクロールできない症状を確認したと当時のログに記録しています。開発者自身のM4 iPad Air 11インチでは元の実装で再現しなかったという報告もありましたが、その端末のOSバージョンは記録上確認できません。端末世代とOSのどちらが挙動差に関係したかは、この比較だけでは決められません。

修正前のSwiftUIコード

v1.2.1の定型文一覧はScrollView → LazyVGrid → Buttonで構成されていました。Buttonの通常アクションは定型文を入力し、セルに付けたLongPressGestureは長押しコピーを呼び出します。長押し後にButtonの入力処理が続かないよう、suppressPhraseTapも使われていました。

以下は実ソースからの抜粋です。セル表示のVStackとButtonStyleは一部省略しています。

// v1.2.1の定型文セルから抜粋
Button {
    if suppressPhraseTap {
        suppressPhraseTap = false
        return
    }
    playSelectionFeedback()
    onSelectPhrase(phrase)
} label: {
    // セルのVStackを配置
}
.buttonStyle(
    KeyboardPressStyle(
        normalBackground: regularKeyColor,
        pressedBackground: pressedRegularKeyColor,
        cornerRadius: keyCornerRadius
    )
)
.simultaneousGesture(
    LongPressGesture(minimumDuration: 0.5)
        .onEnded { _ in
            suppressPhraseTap = true
            onLongPressPhrase(phrase)
        }
)

このコード抜粋は、v1.2.1のapp/PhraseKeyboardExtension/Views/KeyboardRootView.swift(定型文一覧付近)に基づいています。独自のDragGestureやhighPriorityGestureを追加した説明ではありません。

LongPressGestureを外したA/Bテスト

原因を切り分けるため、開発当時の診断版では定型文セルの.simultaneousGesture(LongPressGesture(minimumDuration: 0.5))だけを一時的に無効化したと報告されています。Codexの作業報告では、Buttonと通常タップ処理、ScrollView、レイアウト、suppressPhraseTapは変更していません。診断版では長押しコピーは動きません。

条件定型文セル上のスクロール変更内容
A:v1.2.1相当不可と開発者が報告ButtonにLongPressGestureあり
B:診断版可能になったと開発者が報告LongPressGesture modifierだけ一時無効化

比較対象はiPad Pro 12.9インチ(第2世代)・iOS 17.2 Simulator・横向きで、同じ定型文データを使うよう依頼されていました。その後、開発者は診断版で「スクロール可能になった」と報告しています。

今回のiOS 17.2 Simulator環境では、LongPressGestureを含むセル実装がスクロール阻害の直接条件だったと判断できます。ただし、このA/BだけではSwiftUI内部の具体的な認識機構や、他の端末・OSで同じ現象が起きる範囲までは証明できません。A/Bで確認できたのは診断版でのスクロール改善までです。恒久修正後は実機とSimulatorでスクロールやコピーを確認したとの報告がありますが、Menuの個別操作や各環境の詳細までは記録に明記されていません。

初期のDragGesture案で起きた回帰

初期案ではセル側にDragGesture(minimumDistance: 0)を追加して、タップと移動を判定しようとしました。しかし、元の実装でスクロールできていたM4 iPad Airでも、追加後はセル上からスクロールできなくなりました。追加したGestureと関連処理を撤回すると、セル上と余白の両方でスクロールが復帰したと開発者が確認しています。

この試行はLongPressGestureのA/Bとは別です。セルへ独自DragGestureを加えることが、親のScrollViewを必ず助けるわけではないと分かり、採用案からは外しました。

採用した修正方法:iOS 17はMenu + primaryAction

v1.2.2では、OSによってセル操作を分けました。iOS 17ではMenuの通常操作にprimaryActionを割り当て、タップで入力、長押しでメニューを表示し、メニュー内の「コピー」で既存のコピー処理を呼びます。iOS 18以降は従来のButton+LongPressGestureを維持します。長押しコピーを取り除くのではなく、iOS 17では操作方法を変更した形です。

OS経路通常タップ長押しコピー
iOS 17定型文を入力Menuを表示Menuの「コピー」を選択
iOS 18以降定型文を入力従来どおり長押し長押しで即コピー

iOS 17経路の実ソースからの抜粋です(OS分岐や周辺ヘルパーは省略)。

case .menu:
    Menu {
        Button {
            copyPhrase(phrase)
        } label: {
            Label("コピー", systemImage: "doc.on.doc")
        }
    } label: {
        phraseCellLabel(phrase)
    } primaryAction: {
        playSelectionFeedback()
        onSelectPhrase(phrase)
    }
    .buttonStyle(phraseCellButtonStyle)

OS分岐は#available(iOS 18.0, *)で判定し、iOS 18以降を従来Gesture経路、iOS 17をMenu経路にしています。ScrollViewと基本レイアウトは維持されています。コードはv1.2.2のapp/PhraseKeyboardExtension/Views/KeyboardRootView.swiftおよびapp/PhraseKeyboardExtension/Actions/KeyboardPhraseInserter.swiftに基づいています。

MenuはPhraseBoardで採用した実装上の判断です。同様の症状すべてにMenuが適切だという意味ではなく、実際の画面と操作で確かめて選ぶ必要があります。

v1.2.2の利用者向けアップデート内容はPhraseBoard v1.2.2のアップデート記事にも掲載されています。

修正後のテストと動作確認

当時の作業報告では、swift testは109件すべて成功し、iOS 17.2 Simulator向けDebug BuildとRelease Buildも成功しました。これはビルドと自動テストの結果であり、それ自体がジェスチャー操作の確認を示すものではありません。

その後、開発者は「スクロールやコピーに関しては完了で良さそう。実機確認とシミュレーターで確認しました」と報告しています。修正後の手動確認があったことは確認できますが、この発言には実機の機種・OS、Simulatorの条件、スクロール・タップ・Menu・コピー各操作の個別結果は列挙されていません。そのため、すべての端末・操作が個別にPASSしたという表にはしていません。

検証範囲について:利用者のiPadOS 17.7.11端末でA/Bを行った記録はありません。A/B再現環境はiOS 17.2 Simulatorです。OS境界やすべてのiPadでの再現性も未確認です。

同様の問題を調べるときの確認ポイント

今回の調査で有効だったのは、スクロールコンテナ全体の問題と、子セル上でだけ起きる問題を分けて見たことです。似た症状では、次の順で確認すると原因を絞りやすくなります。

  1. 余白から始めたドラッグと、セル上から始めたドラッグの結果を比べる。
  2. セルがButtonか、どのGesture modifierが付いているかを確認する。
  3. 端末、OS、向き、入力方法、表示データをそろえて比較する。
  4. 診断では一度に一つの処理だけを変え、A/Bの差を見る。
  5. 修正後はスクロールだけでなく、通常タップやコピーなど既存操作も手動で確認する。

この手順は切り分けの観点です。今回のMenu実装を一般解として勧めるものではありません。

まとめ

  • 問題はScrollView全体ではなく、主に定型文セル上でのスクロール操作として報告されました。
  • 開発当時、iOS 17.2 Simulatorでv1.2.1の症状が再現したと記録されています。
  • LongPressGesture modifierだけを無効化した診断版で、セル上のスクロールが可能になったとの報告がありました。
  • v1.2.2ではiOS 17にMenu+primaryAction、iOS 18以降に従来の長押し処理を採用しました。
  • 修正後も実機とSimulatorで確認したとの報告がありますが、個別の端末・操作結果は記録にありません。

今回の事例では、具体的な端末・OSとセル実装をそろえたA/Bテストが原因の切り分けに役立ちました。ジェスチャーの不具合は環境を限定して検証し、その範囲を明示することが大切です。