I am using the locationInView to set the position of my bouton when the user release it. After release, I give the location stored before but in fact, my button is not going back to the correct position.
This my code:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer{
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
static CGPoint startLocation;
if (recognizer.state == UIGestureRecognizerStateBegan) {
startLocation = [recognizer locationInView:self.view];
NSLog(@"Began: %d" @"-" @"%d", (int)startLocation.x , (int)startLocation.y);
}
if (recognizer.state == UIGestureRecognizerStateEnded)
{
NSLog(@"Ended Bef: %d" @"-" @"%d", (int)startLocation.x, (int)startLocation.y);
recognizer.view.center = CGPointMake(startLocation.x, startLocation.y);
startLocation = [recognizer locationInView:self.view];
NSLog(@"Ended Aft: %d" @"-" @"%d", (int)startLocation.x, (int)startLocation.y);
}
}
In fact, the instruction:
recognizer.view.center = CGPointMake(startLocation.x, startLocation.y);
give a wrong effect. Someone know why?
A couple of thoughts:
I'd suggest making sure you capture startLocation
before you do any changing of the center
.
You're using the location of the user's touch for startLocation
. You really should initialize this with the center
of the recognizer.view
. It's exceedingly unlikely that the user started their gesture precisely in the center of the button. And as a result, you're unlikely to return back at the original location.
Somewhat unrelated, but:
You don't need to use CGMakePoint
when resetting the center
of recognizer.view
in the UIGestureRecognizerStateEnded
clause. You can use CGPointMake
if you really want, but it's unnecessary. You can just use startLocation
, if you want.
You might want to animate the returning of the view back to that startLocation
. It's jarring to have it immediately go there.
As an aside, if you've saved startLocation
, you don't need to continually reset the translation
. Just use startLocation
plus translation
. Seems more clear to me, but clearly that's subjective.
I personally think NSStringFromCGPoint
is very useful when logging CGPoint
structures.
So, I'd suggest:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer
{
static CGPoint startLocation;
if (recognizer.state == UIGestureRecognizerStateBegan)
{
startLocation = recognizer.view.center;
NSLog(@"Began: %@", NSStringFromCGPoint(startLocation));
}
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(startLocation.x + translation.x,
startLocation.y + translation.y);
if (recognizer.state == UIGestureRecognizerStateEnded)
{
NSLog(@"Ended Bef: %@", NSStringFromCGPoint(startLocation));
[UIView animateWithDuration:0.25
animations:^{
recognizer.view.center = startLocation;
}];
CGPoint finalLocation = [recognizer locationInView:self.view];
NSLog(@"Ended Aft: %@", NSStringFromCGPoint(finalLocation));
}
}
I think you should try using
startLocation = [recognizer locationOfTouch:0 inView:self.view];
instead of
startLocation = [recognizer locationInView:self.view];