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