
Viewのタップや長押しを認識してアクションを起こす機能が Modifiers の onTapGesture, onLongPressGesture の設定で可能です。
Storyboardでは画面タッチや長押しの機能が UITapGestureRecognizer, UILongPressGestureRecognizer がありました。似たような名前ですがそのまま置き換えはできません
Xcode 12.4
Gesture
- onTapGesture:タップ
 - onLongPressGesture:長押し
 
これらはViewのModifier設定なので Text や Image などViewそれぞれ個別に設定できます。
 
onTapGesture
コードの「Text」あるいはPreviewの「Hello World!」から
画面右のUtility AreaにあるModifierの「Add Modifier」から、
on Tap Gesture を探して追加します。
コードに反映されます。
 
| 
					 1 2 3 4 5  | 
						Text("Hello, world!")     .padding()     .onTapGesture {         /* Code */     }  | 
					
 
タップするたびにテキストが変わるように作ってみると
ContentView.swift
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28  | 
						import SwiftUI struct ContentView: View {     @State var flg = true     var body: some View {         VStack {             if self.flg {                 Text("Hello, World!")                     .onTapGesture {                         self.flg.toggle()                 }             }             else{                 Text("Tapped!")                     .onTapGesture {                         self.flg.toggle()                 }             }         }     } } struct ContentView_Previews: PreviewProvider {     static var previews: some View {         ContentView()     } }  | 
					
 
Toggleを使ってタップされるとフラグが反転するようにしました。
 
これはTextですがButtonのような感じですね。
onTapGestureの定義としてはこれ以外にタップ回数を数えるcountがあります
| 
					 1 2 3 4  | 
						func onTapGesture(     count: Int = 1,      perform action: @escaping () -> Void ) -> some View  | 
					
countを使えば、例えばダブルタップでのに発火するようにすることも可能です。
| 
					 1 2 3 4  | 
						Text("Hello, World!")     .onTapGesture(count: 2) {         print("Tapped!") }  | 
					
onLongPressGesture
Tapと同じよう .onLongPressGesture を追加すると機能します。
 
| 
					 1 2 3 4  | 
						Text("Hello, World!")     .onLongPressGesture {         print("LongPress") }  | 
					
 
ContentView.swift
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30  | 
						import SwiftUI struct ContentView: View {     @State var flg = true     var body: some View {         VStack {             if self.flg {                 Text("Hello, World!")                     .onLongPressGesture {                         self.flg.toggle()                 }             }             else{                 Text("Long Press!")                     .onLongPressGesture {                         self.flg.toggle()                 }             }         }     } } struct ContentView_Previews: PreviewProvider {     static var previews: some View {         ContentView()     } }  | 
					
LongPressですがTapとの違いは持続時間によるのですが、デフォルトでは0.5secですが例えばこれを2.0secに変更することができます。
| 
					 1 2 3 4  | 
						Text("Hello,World!")     .onLongPressGesture(minimumDuration: 2.0) {         print("Long Press 2.0sec") }  | 
					
 
onLongPressGestureの定義は以下のようになって、最小判定時間以外にもいくつかの設定が可能です。
 
| 
					 1 2 3 4 5 6  | 
						func onLongPressGesture(     minimumDuration: Double = 0.5,      maximumDistance: CGFloat = 10,      pressing: ((Bool) -> Void)? = nil,      perform action: @escaping () -> Void   ) -> some View  | 
					
- minimumDuration:最小判定時間、デフォルト0.5sec
 - maximumDistance:最大判定距離、デフォルト10 (CGFloat)
- これは判定範囲が広がるのではなく判定計測が始まってからPress位置が移動しても判定継続される範囲のこと
 
 - pressing:判定の開始と終了をBoolで取り出せる、デフォルトはnil
 - perform:LongPressでのアクション
 
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15  | 
						Text("Hello,World!")     .onLongPressGesture(         minimumDuration: 2.0,         maximumDistance: 1000.0,         pressing:{ pressing in             if pressing {                 print("\(pressing)")             }             else {                 print("\(pressing)")             }     })     {         print("Long Pressed") }  | 
					
 
 
References:
onTapGesture(count:perform:) – Text | Apple Developer
onLongPressGesture(minimumDuration – Apple Developer
minimumDuration – LongPressGesture | Apple Developer
maximumDistance – LongPressGesture | Apple Developer

