how detect swipe gesture direction?
The direction
property only defines the allowed directions that are recognized as swipes, not the actual direction of a particular swipe.
The easiest would be to use two separate gesture recognizers instead. You could also inspect the location of the touch when the gesture starts and when it ends with the locationInView:
method.
Detect swipe gesture direction
I can spot some few problems in your code. It's not a good idea to compare Vector3
with ==
or !=
. Approximate comparison is fine. You are using Input.GetMouseButtonDown
on a mobile platform.
You need to use Input.touches
to do this. Loop over it, store the beginning position in TouchPhase.Began
and then the end position in TouchPhase.Ended
. You can then use both variables to figure it which direction the finger went.
The code below detects swipe direction even when the finger is not yet released with the help of TouchPhase.Moved
. You can disable that by enabling the detectSwipeOnlyAfterRelease
boolean variable. You can also modify SWIPE_THRESHOLD
for sensitivity.
public class SwipeDetector : MonoBehaviour
{
private Vector2 fingerDown;
private Vector2 fingerUp;
public bool detectSwipeOnlyAfterRelease = false;
public float SWIPE_THRESHOLD = 20f;
// Update is called once per frame
void Update()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
fingerUp = touch.position;
fingerDown = touch.position;
}
//Detects Swipe while finger is still moving
if (touch.phase == TouchPhase.Moved)
{
if (!detectSwipeOnlyAfterRelease)
{
fingerDown = touch.position;
checkSwipe();
}
}
//Detects swipe after finger is released
if (touch.phase == TouchPhase.Ended)
{
fingerDown = touch.position;
checkSwipe();
}
}
}
void checkSwipe()
{
//Check if Vertical swipe
if (verticalMove() > SWIPE_THRESHOLD && verticalMove() > horizontalValMove())
{
//Debug.Log("Vertical");
if (fingerDown.y - fingerUp.y > 0)//up swipe
{
OnSwipeUp();
}
else if (fingerDown.y - fingerUp.y < 0)//Down swipe
{
OnSwipeDown();
}
fingerUp = fingerDown;
}
//Check if Horizontal swipe
else if (horizontalValMove() > SWIPE_THRESHOLD && horizontalValMove() > verticalMove())
{
//Debug.Log("Horizontal");
if (fingerDown.x - fingerUp.x > 0)//Right swipe
{
OnSwipeRight();
}
else if (fingerDown.x - fingerUp.x < 0)//Left swipe
{
OnSwipeLeft();
}
fingerUp = fingerDown;
}
//No Movement at-all
else
{
//Debug.Log("No Swipe!");
}
}
float verticalMove()
{
return Mathf.Abs(fingerDown.y - fingerUp.y);
}
float horizontalValMove()
{
return Mathf.Abs(fingerDown.x - fingerUp.x);
}
//////////////////////////////////CALLBACK FUNCTIONS/////////////////////////////
void OnSwipeUp()
{
Debug.Log("Swipe UP");
}
void OnSwipeDown()
{
Debug.Log("Swipe Down");
}
void OnSwipeLeft()
{
Debug.Log("Swipe Left");
}
void OnSwipeRight()
{
Debug.Log("Swipe Right");
}
}
How to detect Swiping UP, DOWN, LEFT and RIGHT with SwiftUI on a View
Based on Benjamin's answer this is a swiftier way to handle the cases
.gesture(DragGesture(minimumDistance: 3.0, coordinateSpace: .local)
.onEnded { value in
print(value.translation)
switch(value.translation.width, value.translation.height) {
case (...0, -30...30): print("left swipe")
case (0..., -30...30): print("right swipe")
case (-100...100, ...0): print("up swipe")
case (-100...100, 0...): print("down swipe")
default: print("no clue")
}
}
)
Detect swipe direction on Jetpack Compose
Modifier.dragGestureFilter
detects dragging in any direction. Pass an instance of DragObserver
and override onDrag
. Here you can detect the swipe direction based on the Offset
. This object has x
and y
values, which are positive or negative based on the direction.
Here's what your code could look like:
Box(
Modifier.dragGestureFilter(
dragObserver = object : DragObserver() {
override fun onDrag(dragDistance: Offset): Offset {
val (x, y) = dragDistance
when {
x > 0 -> { /* right */ }
x < 0 -> { /* left */ }
}
when {
y > 0 -> { /* down */ }
y < 0 -> { /* up */ }
}
}
}
)
)
To actually move the object, you would have to apply Modifier.offset
with values that are updated in onDrag
.
How to recognize swipe in all 4 directions
You need to have one UISwipeGestureRecognizer
for each direction. It's a little weird because the UISwipeGestureRecognizer.direction
property is an options-style bit mask, but each recognizer can only handle one direction. You can send them all to the same handler if you want, and sort it out there, or send them to different handlers. Here's one implementation:
override func viewDidLoad() {
super.viewDidLoad()
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
swipeRight.direction = .right
self.view.addGestureRecognizer(swipeRight)
let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(respondToSwipeGesture))
swipeDown.direction = .down
self.view.addGestureRecognizer(swipeDown)
}
@objc func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case .right:
print("Swiped right")
case .down:
print("Swiped down")
case .left:
print("Swiped left")
case .up:
print("Swiped up")
default:
break
}
}
}
Swift 3:
override func viewDidLoad() {
super.viewDidLoad()
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
swipeRight.direction = UISwipeGestureRecognizerDirection.right
self.view.addGestureRecognizer(swipeRight)
let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
swipeDown.direction = UISwipeGestureRecognizerDirection.down
self.view.addGestureRecognizer(swipeDown)
}
func respondToSwipeGesture(gesture: UIGestureRecognizer) {
if let swipeGesture = gesture as? UISwipeGestureRecognizer {
switch swipeGesture.direction {
case UISwipeGestureRecognizerDirection.right:
print("Swiped right")
case UISwipeGestureRecognizerDirection.down:
print("Swiped down")
case UISwipeGestureRecognizerDirection.left:
print("Swiped left")
case UISwipeGestureRecognizerDirection.up:
print("Swiped up")
default:
break
}
}
}
Swiperjs Detect Swipe Direction?
Finally found it.
on: {
slideChange: (swiper) => {
console.log(swiper.touches.diff < 0);
}
}
Returns true when swipe right, false when left.
NOTE:swiper.touches.diff
will be 0 when the slide is changed by the Navigation Arrows. To do that add event listeners to the buttons, too.
Swift, swipe gesture recognizer direction doesn’t work, can’t seem to get the direction
You need to detect one direction at a time. I would also suggest to add a method to control each swipe direction. For example.
func setUpGestures() {
// Gesture that define a left swipe.
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(Scene.swipeLeft))
swipeLeft.direction = .left
view?.addGestureRecognizer(swipeLeft)
// Do the same for the rest of the directions.
}
@objc func swipeLeft() {
// Do something when the user swipe left.
}
Hope it helps!
Related Topics
Make Timer Run on Background iOS for More Than 3 Minutes
Storyboard Is Not Showing Custom Color Hex Code in Xcode 12.0.1
How to Set Action for Uibutton in Uitableviewcell
JSON Text Did Not Start with Array or Object and Option to Allow Fragments Not Set
Swift 3: Unrecognized Selector Sent to Instance Xcode 8
How to Use Local-Only Project via Cocoapods
How to Load Icarousel View from Storyboard or Xib
Accessing Core Data Stack in Mvvm Application
Swiftui Show/Hide Title Issues with Navigationbar
iOS Web Page Errors Over Cellular Data But Not Over Wifi? Recent Change to At&T Cellular Network
Alamofire: Finished with Error - Code: -1001
iOS Name of This Way of Building and Returning an Object in Objective-C
How to Make Generics in Collection Type Constraint
Doing Undo and Redo with Cglayer Drawing
iOS 9 Objective-C Screen Size Issues
Swift - Fatal Error: Array Index Out of Range
iOS Scatter Core Plot with a Gap
Timestamp Function That Has Been Working Reliably Just Caused Exc_Bad_Instruction