【SwiftUI】主要なジェスチャについてまとめる

## はじめに

SwiftUIのジェスチャについて学習したので、備忘録として内容をまとめます。 主要なジェスチャの一覧とその概要をまとめ、どのような場面で使うのかを解説します。

---

## 環境
【Xcode】16.2
【iOS】18.2
【macOS】Sequoia 15.3.1

---

## SwiftUIのジェスチャとは？

**ジェスチャ**とは、ユーザーが画面を操作する行動（タップ、ドラッグ、ピンチなど）を指します。 SwiftUIでは、これらのジェスチャを**モディファイア**としてビューに簡単に適用できます。

### 💡 使いどころ

- **タップ** → 画面上の要素を選択・決定
- **長押し** → サブメニューや詳細アクションの表示
- **スワイプ** → 要素の移動や削除
- **ピンチ・回転** → 画像の拡大縮小、回転

---

## SwiftUIの主要なジェスチャ一覧

| ジェスチャ                  | 主な用途          | 主なプロパティ                |
| ---------------------- | ------------- | ---------------------- |
| `.onTapGesture`        | タップ認識（回数指定可能） | `count:`（タップ回数）        |
| `.onLongPressGesture`  | 長押し認識         | `minimumDuration:`（秒数） |
| `DragGesture`          | ドラッグ（スワイプ）    | `translation`（移動量）     |
| `MagnificationGesture` | ピンチ（拡大・縮小）    | `scale`（拡大倍率）          |
| `RotationGesture`      | 回転            | `angle`（回転角度、ラジアン単位）   |
| `simultaneousGesture`  | 複数ジェスチャ同時認識   | -                      |
| `sequencedGesture`     | ジェスチャ順序の指定    | -                      |

---

## 各ジェスチャの概要と使い方

### 1. `.onTapGesture`（タップジェスチャ）

タップを認識し、回数を指定できます。

```swift
struct ContentView: View {
    @State private var message = "タップしてね"

    var body: some View {
        Text(message)
            .onTapGesture(count: 2) {
                message = "ダブルタップされました"
            }
    }
}
```

### 2. `.onLongPressGesture`（長押しジェスチャ）

長押しを認識し、押下時間を指定できます。

```swift
struct ContentView: View {
    @State private var message = "長押ししてね"

    var body: some View {
        Text(message)
            .onLongPressGesture(minimumDuration: 1.5) {
                message = "1.5秒長押しされました"
            }
    }
}
```

### 3. `DragGesture`（ドラッグジェスチャ）

要素のドラッグ（スワイプ）を認識できます。

```swift
struct ContentView: View {
    @State private var offset: CGSize = .zero

    var body: some View {
        Circle()
            .frame(width: 100, height: 100)
            .offset(offset)
            .gesture(
                DragGesture()
                    .onChanged { value in
                        offset = value.translation
                    }
            )
    }
}
```

### 4. `MagnificationGesture`（ピンチジェスチャ）

要素の拡大・縮小を認識できます。

```swift
struct ContentView: View {
    @State private var scale: CGFloat = 1.0

    var body: some View {
        Image(systemName: "photo")
            .resizable()
            .frame(width: 200, height: 200)
            .scaleEffect(scale)
            .gesture(
                MagnificationGesture()
                    .onChanged { value in
                        scale = value
                    }
            )
    }
}
```

#### 🛠️ シミュレーターでピンチ操作を試す方法

1. シミュレーターを起動

2. **Optionキーを押しながら**マウスを使ってピンチイン・アウトを行います。

   - 画面上に2つの円が表示され、指の動きをシミュレートできます。
   - マウスをドラッグしてピンチの拡大・縮小を確認できます。

### 5. `RotationGesture`（回転ジェスチャ）

要素の回転を認識できます。

```swift
struct ContentView: View {
    @State private var angle: Angle = .zero

    var body: some View {
        Image(systemName: "arrow.right.circle")
            .resizable()
            .frame(width: 200, height: 200)
            .rotationEffect(angle)
            .gesture(
                RotationGesture()
                    .onChanged { value in
                        angle = value
                    }
            )
    }
}
```
※シミュレーターでは、ピンチ操作と同様にOptionキーを押しながらマウスを回転させることで動作が確認できます。

### 6. `simultaneousGesture`（複数ジェスチャ同時認識）

複数のジェスチャを同時に認識できます。

```swift
struct ContentView: View {
    @State private var message = ""
    
    var body: some View {
        Text(message.isEmpty ? "タップまたは長押し" : message)
            .gesture(
                TapGesture()
                    .onEnded { message = "タップされました" }
            )
            .simultaneousGesture(
                LongPressGesture()
                    .onEnded { _ in message = "長押しされました" }
            )
    }
}
```

---

## ジェスチャの選び方

| 目的               | 適切なジェスチャ                 |
| ---------------- | ------------------------ |
| ✅ クリック・タップを検知したい | `.onTapGesture`          |
| ✅ 長押しを検知したい      | `.onLongPressGesture`    |
| ✅ スワイプで移動させたい    | `DragGesture`            |
| ✅ ピンチイン・アウトで拡大縮小 | `MagnificationGesture`   |
| ✅ 画像やビューを回転させたい  | `RotationGesture`        |
| ✅ 複数ジェスチャを併用したい  | `simultaneousGesture` など |