maui-gestures について
.NET MAUI でタッチ、ポインター、ドラッグ&ドロップを実装する開発者向けのジェスチャーガイドです。非推奨 API、プラットフォーム差、競合、MVVM のコマンド利用を説明します。
主な機能
- 01ジェスチャー認識器の選択指針
- 02座標とホバーのプラットフォーム差
- 03ドラッグ&ドロップと副ボタンの動作
- 04ジェスチャー組み合わせの競合に関する注意
- 05MVVM のコマンド実践
活用シーン
- 01マウスホバーとタッチ操作を実装
- 02Android のパンやスワイプの挙動を調査
- 03ドロップ先を設定
- 04ビューモデルでテストしやすい操作方式を選択
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-gesturesインストール後、Claude Code で/maui-gesturesを入力して読み込まれたか確認します。
同梱ファイルreferences/gestures-api.md
詳細
.NET MAUI ジェスチャー認識機能
非推奨 API に関する警告
⚠️ .NET 10 では、
ClickGestureRecognizerは非推奨です。代わりにTapGestureRecognizer(タッチ/スタイラス)とPointerGestureRecognizer(マウスのホバー/押下)を使用してください。
よくある間違い
方向ごとに SwipeGestureRecognizer を 1 つ使用する
1 つの認識機能が処理できる方向は 1 つだけです。1 つの認識機能に複数の方向を追加すると、ほとんどのプラットフォームでエラーもなく機能しなくなります。
<SwipeGestureRecognizer Direction="Left,Right" Swiped="OnSwiped" />
<SwipeGestureRecognizer Direction="Left" Swiped="OnSwiped" />
<SwipeGestureRecognizer Direction="Right" Swiped="OnSwiped" />
AllowDrop の既定値は false
このプロパティを設定し忘れると、ドロップ先はドロップを無視します。
<StackLayout>
<StackLayout.GestureRecognizers>
<DropGestureRecognizer Drop="OnDrop" />
</StackLayout.GestureRecognizers>
</StackLayout>
<StackLayout>
<StackLayout.GestureRecognizers>
<DropGestureRecognizer AllowDrop="True" Drop="OnDrop" />
</StackLayout.GestureRecognizers>
</StackLayout>
ホバー効果に TapGestureRecognizer を使用する
タップ認識機能はポインターの移動を追跡しません。ホバー効果には PointerGestureRecognizer を使用してください。これにより PointerOver の視覚状態も有効になります。
<Border>
<Border.GestureRecognizers>
<TapGestureRecognizer Command="{Binding HoverCommand}" />
</Border.GestureRecognizers>
</Border>
<Border>
<Border.GestureRecognizers>
<PointerGestureRecognizer PointerEnteredCommand="{Binding HoverInCommand}"
PointerExitedCommand="{Binding HoverOutCommand}" />
</Border.GestureRecognizers>
</Border>
注意が必要なプラットフォーム間の違い
パンの delta 座標はプラットフォームによって異なる
| プラットフォーム | TotalX / TotalY の基準 |
|---|---|
| iOS / Mac Catalyst | ジェスチャーの開始位置 |
| Android | 前回のイベント(開始位置ではありません!) |
| Windows | ジェスチャーの開始位置 |
サブピクセル単位の精度が重要な場合は、TotalX/TotalY を直接使わず、Android の delta を手動で累積して正規化してください。
ポインターのホバーはマウス/トラックパッドのみ
タッチデバイスでは、PointerGestureRecognizer のイベントは押下時と解放時に発生しますが、タッチの合間のホバーは追跡されません。タッチベースの UI で PointerMoved に依存しないでください。
アプリ間のドラッグ&ドロップ
| プラットフォーム | サポート状況 |
|---|---|
| iPadOS / Mac Catalyst | ✅ はい |
| Windows | ✅ はい |
| Android | ❌ いいえ |
セカンダリボタン(右クリック)
| プラットフォーム | 動作 |
|---|---|
| iOS / Mac Catalyst | Buttons = ButtonsMask.Secondary が機能します |
| Windows | Buttons = ButtonsMask.Secondary が機能します |
| Android | 長押しにフォールバックします。実際の右クリックには対応していません |
ジェスチャーの組み合わせによる競合
同じビューでパンとスワイプを組み合わせると、Android では競合します。パンが始まる前にスワイプがジェスチャーを消費する場合があります。すべてのプラットフォームでテストするか、一度にどちらか 1 つだけを使用してください。
タップとパンの組み合わせは問題なく動作します。素早いタップではタップが発生し、継続的なドラッグではパンが発生します。
MVVM のベストプラクティス
テスト可能なビューモデルには、イベントよりもコマンドを優先してください。実行時の動作はどちらも同じですが、コマンドのほうがモックやテストが容易です。
<TapGestureRecognizer Command="{Binding TapCommand}" />
<TapGestureRecognizer Tapped="OnTapped" />
すぐに使えるルール
- 方向ごとに
SwipeGestureRecognizerを 1 つ使用する - ホバーには
TapGestureRecognizerではなくPointerGestureRecognizerを使用する - ドロップ先に
AllowDrop="True"を設定する。既定値はfalse - Android ではパンの delta を正規化する(開始位置ではなく、前回のイベントを基準とする)
- MVVM ではイベントよりもコマンドを優先する
- 非推奨の
ClickGestureRecognizerの代わりにTapGestureRecognizerを使用する(.NET 10) - タッチベースの UI では
PointerMovedに依存しない。ホバーは追跡されない