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 as you go around the center of the box needs to be adjusted according to the angle and I can't figure out how.
I've included pictures of what a 180 rotation looks like but where the finger is during the rotation. I just don't know how to adjust to make the block stay with your finger appropriately. And heres a video just to clarify because it is strange behavior. http://tinypic.com/r/mhx6a1/5
EDIT: Here is a real world video of what should be happening. The problem being that in the iPad video your finger is moving where in the real world your finger would be cemented in a particular place on the item moving. The math needed is to adjust your touch location along the angle with a difference from the actual center. I just can't figure out the math. http://tinypic.com/r/4vptnk/5
Thanks very much!
- (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)];
}
}
I've finally solved this issue and have it working perfectly. Persistence am I right??
Here is the code for the 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 helps someone else in the future. Happy Coding :)
Based on touch events https://github.com/kirbyt/KTOneFingerRotationGestureRecognizer
Helped me to solve similar problem
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With