I have a series of UIViews which I animate along an arc. Each view has a UIPanGestureRecognizer on it which before any animation occurs works as expected.
However after animating the views (with the method below which animates a view's layer) the gestures do not work as expected; in fact it appears as if they work in their original screen positions.
I've tried various things including matching up the views frame and/ or bounds with that on the animated layer and even removing the existing gestures and creating and adding them again (not shown below).
If anyone knows what's going on or can get me on the road to fixing the issue it would be greatly appreciated.
EDIT: iMartin's suggestion to change
pathAnimation.removedOnCompletion = NO;
to
pathAnimation.removedOnCompletion = YES;
and
view.layer.position = ... //
have put me on the way to fixing the issue.
Original Code:
- (void)animateUIViewAlongArc:(UIView*)view clockwise:(BOOL)clockwise duration:(float)duration
{
[UIView animateWithDuration:duration animations:^{
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimationanimationWithKeyPath:@"position"];
pathAnimation.calculationMode = kCAAnimationPaced;
pathAnimation.fillMode = kCAFillModeForwards;
pathAnimation.removedOnCompletion = NO;
pathAnimation.repeatCount = 1;
CGPoint viewCenter = view.objectCenter;
CGMutablePathRef arcPath = CGPathCreateMutable();
CGPathMoveToPoint(arcPath, NULL, viewCenter.x, viewCenter.y);
float angleOfRotation = self.angleIncrement;
if (clockwise == NO)
{
angleOfRotation *= -1.0f;
}
float fullwayAngle = view.angle + angleOfRotation;
CGPoint fullwayPoint = pointOnCircle(self.center, self.radius, fullwayAngle);
CGPathAddRelativeArc(arcPath, NULL, self.center.x, self.center.y, self.radius, view.angle, angleOfRotation);
pathAnimation.path = arcPath;
CGPathRelease(arcPath);
[view.layer addAnimation:pathAnimation forKey:@"arc"];
view.angle = fullwayAngle;
view.objectCenter = fullwayPoint;
} completion:^(BOOL finished){
if (finished)
{
CGRect frame = view.layer.frame;
CGRect bounds = view.layer.bounds;
view.frame = frame;
view.bounds = bounds;
}
}];
}
Did you check the frame of the view/layer after the animation?
I think the problem is, that what you see is not what you get. The layer itself didn't changes its position/frame, but just its presentationLayer
did. Presentation layer is what you actualy see onthe screen. You could see this if you remove this line:
pathAnimation.removedOnCompletion = NO; // Delete or set to YES
Setting this to NO
caused the presentation layer to be on screen at different position than your view.
What you should do, is to set final position to the layer just before adding the animation to it.
view.layer.position = finalPosition; // You should calculate this
[view.layer addAnimation:pathAnimation forKey:@"arc"];
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