Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect Swiping UP, DOWN, LEFT and RIGHT with SwiftUI on a View

I'm getting into building Apple Watch apps.

What I'm currently working on will require me to make use of detecting swipes in the four main directions (UP, DOWN, LEFT and RIGHT)

The problem is I have no idea how to detect this. I've been looking around and I'm reaching dead ends.

What can I do to my view below to just print swiped up when the user swipes UP on the view?

struct MyView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

Thanks.

like image 802
Barry Michael Doyle Avatar asked Mar 27 '20 11:03

Barry Michael Doyle


People also ask

How do you add a swipe gesture to a view in Swift?

We can use the createSwipeGestureRecognizer(for:) method in the view controller's viewDidLoad() method to create a swipe gesture recognizer for each direction. We pass the result of createSwipeGestureRecognizer(for:) to the addGestureRecognizer(_:) method.

How do you detect swipe?

Swiping in touch is the act of quickly moving your finger across the touch surface in a certain direction.


3 Answers

You could use DragGesture

.gesture(DragGesture(minimumDistance: 0, coordinateSpace: .local)
                    .onEnded({ value in
                        if value.translation.width < 0 {
                            // left
                        }

                        if value.translation.width > 0 {
                            // right
                        }
                        if value.translation.height < 0 {
                            // up
                        }

                        if value.translation.height > 0 {
                            // down
                        }
                    }))
like image 127
Sorin Lica Avatar answered Oct 14 '22 07:10

Sorin Lica


With the other solutions being a bit inconsistent on a physical device, I decided to come up with another one that seems to be much more consistent across different screen sizes as there are no hardcoded values except for the minimumDistance.

.gesture(DragGesture(minimumDistance: 20, coordinateSpace: .global)
            .onEnded { value in
                let horizontalAmount = value.translation.width
                let verticalAmount = value.translation.height
                
                if abs(horizontalAmount) > abs(verticalAmount) {
                    print(horizontalAmount < 0 ? "left swipe" : "right swipe")
                } else {
                    print(verticalAmount < 0 ? "up swipe" : "down swipe")
                }
            })
like image 33
Fynn Becker Avatar answered Oct 14 '22 05:10

Fynn Becker


If you want one that is more "forgiving" to the directionality of the swipe, you can use a few more conditionals to help even it out:

EDIT: did some more testing, apparently the values for the second conditional add some confusion, so I adjusted them to remove said confusion and make the gesture bulletproof (drags to the corners will now come up with "no clue" instead of one of the gestures)...

let detectDirectionalDrags = DragGesture(minimumDistance: 3.0, coordinateSpace: .local)
.onEnded { value in
    print(value.translation)
    
    if value.translation.width < 0 && value.translation.height > -30 && value.translation.height < 30 {
        print("left swipe")
    }
    else if value.translation.width > 0 && value.translation.height > -30 && value.translation.height < 30 {
        print("right swipe")
    }
    else if value.translation.height < 0 && value.translation.width < 100 && value.translation.width > -100 {
        print("up swipe")
    }
    else if value.translation.height > 0 && value.translation.width < 100 && value.translation.width > -100 {
        print("down swipe")
    }
    else {
        print("no clue")
    }
like image 28
Benjamin B. Avatar answered Oct 14 '22 07:10

Benjamin B.