Viewのタップや長押しを認識してアクションを起こす機能が Modifiers の onTapGesture, onLongPressGesture の設定で可能です。
Storyboardでは画面タッチや長押しの機能が UITapGestureRecognizer, UILongPressGestureRecognizer がありました。似たような名前ですがそのまま置き換えはできません
Gesture
- onTapGesture:タップ
- onLongPressGesture:長押し
これらはViewのModifier設定なので Text や Image などViewそれぞれ個別に設定できます。
onTapGesture
例として「Hello World」にonTapGestureの機能を追加してみましょう
コードの「Text」あるいはPreviewの「Hello World!」から
画面右のUtility AreaにあるModifierの「Add Modifier」にて
on Tap Gesture を探して追加します。
onTapGestureがコードに反映されます。
1 2 3 4 5 |
Text("Hello, world!") .padding() .onTapGesture { /* Code */ } |
タップするたびにテキストが変わるようにif文でtoggleを使ってみます
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@State var flg = true ... if self.flg { Text("Hello, World!") .onTapGesture { self.flg.toggle() } } else{ Text("Tapped!") .onTapGesture { self.flg.toggle() } } |
ContentView
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を使えば、例えばダブルタップで発火するようにすることも可能です。
連続してタップするケースでゆっくり2回では発火しない
1 2 3 4 |
Text("Hello, World!") .onTapGesture(count: 2) { print("Tapped!") } |
onLongPressGesture
Tapと同じよう .onLongPressGesture を追加しますが今回はPreviewの
addModifireから選択
Text に.onLongPressGesture が追加されました
1 2 3 4 |
Text("Hello, World!") .onLongPressGesture { print("LongPress") } |
同じようにtoggleで切り替えを試してみましょう
ContentView
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