Drag + rotate using UIPanGestureRecognizer.

I am doing some drag and rotation calculations using UIPanGestureRecognizer. The rotation angle is correct, and the drag location is almost correct. The problem is that when you go around the center of the box, you need to adjust it according to the angle, and I cannot figure out how to do it.

I included photos of what 180 rotation looks like, but where is the finger during the rotation. I just don’t know how to set it so that the block remains with your finger. And heres the video just to clarify, because it's weird behavior. http://tinypic.com/r/mhx6a1/5

EDIT: Here is a real world video of what is going to happen. The problem is that in the iPad video your finger moves, where in the real world your finger will be fixed in a certain place on the moving object. Math is needed to adjust your touch location along an angle with the difference from the actual center. I just can't understand the math. http://tinypic.com/r/4vptnk/5

first shot

second shot

third shot

Many thanks!

- (void)handlePan:(UIPanGestureRecognizer *)gesture { if (gesture.state == UIGestureRecognizerStateBegan) { // set original center so we know where to put it back if we have to. originalCenter = dragView.center; } else if (gesture.state == UIGestureRecognizerStateChanged) { [dragView setCenter:CGPointMake( originalCenter.x + [gesture translationInView:self.view].x , originalCenter.y + [gesture translationInView:self.view].y )]; CGPoint p1 = button.center; CGPoint p2 = dragView.center; float adjacent = p2.x-p1.x; float opposite = p2.y-p1.y; float angle = atan2f(adjacent, opposite); [dragView setTransform:CGAffineTransformMakeRotation(angle*-1)]; } } 
+6
source share
2 answers

I finally solved this problem and it works great. Persistence Am I Right?

Here is the code for a solution with a few comments to explain the changes.

 - (void)handlePan:(UIPanGestureRecognizer *)gesture { if (gesture.state == UIGestureRecognizerStateBegan) { // Get the location of the touch in the view we're dragging. CGPoint location = [gesture locationInView:dragView]; // Now to fix the rotation we set a new anchor point to where our finger touched. Remember AnchorPoints are 0.0 - 1.0 so we need to convert from points to that by dividing [dragView.layer setAnchorPoint:CGPointMake(location.x/dragView.frame.size.width, location.y/dragView.frame.size.height)]; } else if (gesture.state == UIGestureRecognizerStateChanged) { // Calculate Our New Angle CGPoint p1 = button.center; CGPoint p2 = dragView.center; float adjacent = p2.x-p1.x; float opposite = p2.y-p1.y; float angle = atan2f(adjacent, opposite); // Get the location of our touch, this time in the context of the superview. CGPoint location = [gesture locationInView:self.view]; // Set the center to that exact point, We don't need complicated original point translations anymore because we have changed the anchor point. [dragView setCenter:CGPointMake(location.x, location.y)]; // Rotate our view by the calculated angle around our new anchor point. [dragView setTransform:CGAffineTransformMakeRotation(angle*-1)]; } } 

Hope my month + struggle and solution will help someone else in the future. Happy coding :)

+8
source

Based on touch events https://github.com/kirbyt/KTOneFingerRotationGestureRecognizer

Helped me solve a similar problem

+3
source

Source: https://habr.com/ru/post/913363/


All Articles