[SwiftUI] Swipeの検知と実装

     

TAGS:

⌛️ 2 min.

SwiftUIでのDragは、DragGesture を使うと簡単に実装できますが、Swipeはどうでしょうか?調べてみました。

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")
        }
    })
)

サンプル実装

表示されているテキストを左右にスワイプすることで表示位置が変更されるサンプル実装です

テキストを右スワイプすると、テキストが右にずれていきます

origin
rightSwiped

左スワイプも同様に、テキストが左にずれていきます。

origin
leftSwiped

コード


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 の値をチェックすることとなります。

説明は以上です。

コメントを残す

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