SwiftUIでのDragは、DragGesture を使うと簡単に実装できますが、Swipeはどうでしょうか?調べてみました。
Sponsor Link
SwipeGestureはありません
Swipeしたかどうかの検知をするための、SwipeGesture はありません。
iOS15, macOS12 以降では、.swipeActions という View Modifier で Swipe 動作がサポートされるようになりました。
UIKit で使っていた GestureRecognizer には、UISwipeGestureRecognizer が用意されているのですが、SwiftUI には、用意されていませんでした。
では、どうするか・・・・DragGesture を使って、実現します。
DragGesture を使って、Swipe を検知する
DragGesture には、3つの Closure を指定できます。
使用する closure の選択
- onChanged
- 位置に変更があると実行されます
- onEnded
- ドラッグ後に実行されます
- updating
- 少し特殊なので説明は、別途
Swipe は、Swipe途中ではなく、Swipe後に反応すれば良いので、onEnded を使って実装します。
closure に渡されてくる引数
ドキュメントをみるとわかるように、DragGesture.Value が渡されます。
このstructには、いろいろと情報が含まれていますが、ここでは、translation 属性を使用します。この translation 属性に、ドラッグ開始位置からの移動情報が含まれています。
CGSize 型ですので、.width で X 方向の距離、.height で Y 方向の距離を取得できます。
例えば、右と左の水平方向のみのスワイプは、以下のようなDragGestureを使用することで、それぞれの処理を行わせることができます。
.gesture(DragGesture()
.onEnded({ value in
if (abs(value.translation.width) 10) { return } // too small movement, ignore note: 10 is default value for minimumDistance
if (value.translation.width 0 ) {
// swiped to left
print("swipe to left")
} else if (value.translation.width > 0 ) {
// swiped to right
print("swipe to right")
}
})
)
サンプル実装
表示されているテキストを左右にスワイプすることで表示位置が変更されるサンプル実装です
テキストを右スワイプすると、テキストが右にずれていきます
左スワイプも同様に、テキストが左にずれていきます。
struct ContentView: View {
@State private var labelPosX:CGFloat = 0
var body: some View {
Text("Hello, World!")
.offset(x: labelPosX)
.gesture(DragGesture()
.onEnded({ value in
if (abs(value.translation.width) < 10) { return } // too small movement, ignore note: 10 is default value for minimumDistance
if (value.translation.width < 0 ) {
// swiped to left
print("swipe to left")
self.labelPosX -= 30
} else if (value.translation.width > 0 ) {
// swiped to right
print("swipe to right")
self.labelPosX += 30
}
})
)
}
}
上下へのスワイプであれば、translation.height の値をチェックすることとなります。
説明は以上です。
Sponsor Link