1

I have an if statement checking the velocity of the object I'm moving (an image). The point of the statement is to determain which way the image is being influenced, and once it does so, it locks either the X or Y plane, so that it's a smooth left and right movement, or smooth up and down movement.

As the code is below (checking first for right movement, then left, so on) the movement is much smoother if you're going left or right. However, sometimes, when trying to influence the movement up or down, it sort of gets locked into the left and right movement. This I believe is because it's looking first in the if statement for left and right movement. If I move the up and down to be checked first, the left and right movement gets choppy instead. Is there a better way to do this?

let velocity = recognizer.velocity(in: self.view) if velocity.x > 75 { movingRight = true myBlocks[objectDragging].center.y = CGFloat(initPosy) } else if velocity.x < -75 { movingLeft = true myBlocks[objectDragging].center.y = CGFloat(initPosy) } else if velocity.y < -30 { movingUp = true myBlocks[objectDragging].center.x = CGFloat(initPosx) } else { movingDown = true myBlocks[objectDragging].center.x = CGFloat(initPosx) } 

2 Answers 2

2

Example of a problem with this is when you have a very fast movement up and slightly to the right, like this: x = 78, y = -450 This is definitely an example of vertical movement, but for your algorithm to know it you need to compare velocity.x and velocity.y values. Better way to do this would be to instead check which axis has highest absolute value of velocity. In your case it also needs to be scaled (as threshold for horizontal movement is 75 and for vertical movement is 30).

if abs(velocity.x) > abs(velocity.y * 2.5) { // this is horizontal movement } else { // this is vertical movement } 
Sign up to request clarification or add additional context in comments.

2 Comments

On the other hand, you might want to do it the way that for example Apple does in Safari - it locks scrolling to horizontal when you start with horizontal finger movement, and locks it to vertical only when you start with vertical finger movement. But if you start moving with at an angle of 45 degrees or somewhere around it, scrolling is omnidirectional and doesn't get locked to any axis.
Thanks for the suggestion, this will help a lot. I hadn't thought of doing an explicit comparison.
1

Perhaps you should check which direction has the greater magnitude first, and then decide if its positive or negative.

let velocity = recognizer.velocity(in: self.view) if abs(velocity.x) > abs(velocity.y) { //going left/right if velocity.x > 0 { movingRight = true myBlocks[objectDragging].center.y = CGFloat(initPosy) } else { movingLeft = true myBlocks[objectDragging].center.y = CGFloat(initPosy) } } else { if velocity.y > 0 { movingUp = true myBlocks[objectDragging].center.x = CGFloat(initPosx) } else { movingDown = true myBlocks[objectDragging].center.x = CGFloat(initPosx) } } 

As @johnyu suggests - you can use a factor to compare horizontal vs vertical movement.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.