[SwiftUI] onLongPressGesture/ LongPressGesture の動作

SwiftUI2021

     
⌛️ 2 min.

onLongPressGesture/ LongPressGesture について、説明してみます。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS14.5
  • Xcode 16 Beta
  • iOS 17.5
  • Swift 5.9

onLongPressGesture/ LongPressGesture

SwiftUI で gesture に対応するために用意されている View Modifier の1つです。


参考
onLongPressGestureApple Developer Documentation

内部的には、LongPressGesture が使用されています。


参考
LongPressGestureApple Developer Documentation

onLongPressGesture の引数

onLongPressGesture に指定できる引数は、以下です。

・minimumDuration: Double
これは、LongPress と認識されるのに必要な最小時間を指定します。Duration ではなく、TimeInterval 的に Double で指定します。デフォルトでは、0.5 (秒) です。

・maxiumDistance: CGFloat
これは、LongPress 中に移動量として許容される距離を指定します。
デフォルトでは、10 です。

・perform: @escaping () -> Void
LongPressと認識されたタイミングで実行される closure を指定します。

注意

LongPress と “認識されたタイミング” で実行されます。
Press が終了したタイミングではありません。

・onPressingChanged: ((Bool) -> Void)?
Press の状態が変更されたときに実行されます。引数には、状態(Bool値) が渡されてきます。

注意

最初の状態変化は、(LongPress と認識される前の) Press が開始されたタイミングです。
次の状態変化は、LongPress と認識された タイミングです。
以降は、Press を終了しても 通知は行われません。

LongPressGesture 引数

LongPressGesture に指定できる引数は、以下です。

・minimumDuration: Double
これは、LongPress と認識されるのに必要な最小時間を指定します。Duration ではなく、TimeInterval 的に Double で指定します。
デフォルトでは、0.5 (秒) です。

・maxiumDistance: CGFloat
これは、LongPress 中に移動量として許容される距離を指定します。
デフォルトでは、10 です。

LongPressGesture の onChanged, onEnded

LongPressGesture を使用すると、ジェスチャー検知時の振る舞いは、onChanged/ onEnded で指定することになります。

onChanged は、Press が始まると true を引数として呼び出されます。(LongPress と検知される前、Press 開始時に呼び出されます)

onEnded は、LongPress と検知されると、true を引数として呼び出されます。

注意

なんとなく、onEnded と (2回目呼び出し時の) onPressingChanged は、同じ値を受け取りそうな気がしますが、一致しません。

(LongPress 検知時の onPressingChanged は、false が引数として渡されてきますが、onEnded には true が引数として渡されてきます。
この state の値に応じて 処理を行う場合には注意が必要です。

シーケンス図

それぞれを使用したときのシーケンス図を作成しました。

onLongPressGesture

onLongPressGesture を使うと、以下のようなシーケンスになります。

---
title: onLongPressGesture
---
sequenceDiagram
  participant View
  participant onPressingChanged
  participant perform
  View->View: start Press
  activate View
  View->>onPressingChanged: called with true
  alt minimumDuration passed
  View->>onPressingChanged: called with false
  View->>perform: called (without value)
  else less than minimumDuration 
  View->>onPressingChanged: called with false
  end 
  View->View: end Press
  deactivate View
  note over View, perform: nothing happens

LongPressGesture

LongPressGesture を使うと、以下のようなシーケンスになります。

---
title: LongPressGesture
---
sequenceDiagram
  participant View
  participant onChanged
  participant onEnded
  View->View: start Press
  activate View
  View->> onChanged: called with true
  alt minimumDuration passed
  View->> onEnded: called with true
  else less than minimumDuration 
  note over View, perform: nothing happens
  end 
  View->View: end Press
  deactivate View
  note over View, perform: nothing happens

コード例

上記のシーケンス図は、以下のコードでの動作から作図しています。

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2024/07/28
//  © 2024  SmallDeskSoftware
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Circle().foregroundColor(.green).frame(width: 80, height: 80)
                .onLongPressGesture(minimumDuration: 5.0,
                                    perform: {
                    print("perform")
                }, onPressingChanged: { state in
                    print("onPressingChanged: \(state)")
                })

            Circle().foregroundColor(.red).frame(width: 80, height: 80)
                .gesture(LongPressGesture(minimumDuration: 5.0)
                    .onChanged({ change in
                        print("onChanged: \(change)")
                    })
                    .onEnded({ end in
                        print("onEnded: \(end)")
                    })
                )
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

まとめ

onLongPressGesture/ LongPressGesture の動作についてまとめてみました。

onLongPressGesture/ LongPressGesture の動作
  • minimumDuration 経過時に処理を行うための Gesture
  • Press 終了時に何か呼び出されることはない
  • onLongPressGesture と LongPressGesture では呼び出されるタイミング/値が異なる

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

SwiftUI おすすめ本

SwiftUI を理解するには、以下の本がおすすめです。

SwiftUI ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です