Why does my view jump when setting the layer anchorPoint in an animation block?

半城伤御伤魂 提交于 2019-12-22 17:39:08

问题


I have a UIPanGestureRecognizer attached to a view in my iOS app. I copied the code from the Touches sample app for the pan handler. When the gesture starts, my code:

  • Records the original anchor point and center.
  • Changes the anchor point and center to be around the user's fingers, like so:

    CGPoint locationInView = [gestureRecognizer locationInView:target];
    CGPoint locationInSuperview = [gestureRecognizer locationInView:target.superview];
    target.layer.anchorPoint = CGPointMake(
        locationInView.x / target.bounds.size.width,
        locationInView.y / target.bounds.size.height
    );
    target.center = locationInSuperview;
    

As the gesture progresses, the pan handler continuously changes the center to track the finger movement. So far so good.

When the user lets go, I want the view to animate back to its original starting point. The code that does that looks like this:

[UIView animateWithDuration:2 delay:0 options:UIViewAnimationCurveEaseOut animations:^{
    target.center            = originalCenter;
    target.layer.anchorPoint = originalAnchorPoint;
}];

And that does animate the view back to its original starting point. However, before the animation starts, the view jumps to a different spot in the UI. IOW, let go, it jumps, then it animates back to where it belongs.

I thought perhaps I needed to set the anchor point and center outside the animation, perhaps setting the center to the location in the super view, like when the gesture begins, but that seems to make no difference.

What am I missing here? How can I prevent the jump when the user lets go?


回答1:


I suspect two issues without trying out what you are doing:

Changing the anchor point changes a view's/layer's position. In order to change an anchor point without modification of the position, you can use some helper like this one:

-(void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view
{
    CGPoint newPoint = CGPointMake(view.bounds.size.width * anchorPoint.x, view.bounds.size.height * anchorPoint.y);
    CGPoint oldPoint = CGPointMake(view.bounds.size.width * view.layer.anchorPoint.x, view.bounds.size.height * view.layer.anchorPoint.y);

    newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
    oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);

    CGPoint position = view.layer.position;

    position.x -= oldPoint.x;
    position.x += newPoint.x;

    position.y -= oldPoint.y;
    position.y += newPoint.y;

    view.layer.position = position;
    view.layer.anchorPoint = anchorPoint;
}

(I'm using that myself in my projects. Found here: Changing my CALayer's anchorPoint moves the view)

Your animation sets the anchor point back to its original value. You should use the helper above to reset the anchor point. This ensures that the view won't move when changing the anchor. You'll have to do this outside of the animation. Afterwards, use an animation block to change the view's center and animate it to where you want it to be.



来源:https://stackoverflow.com/questions/10468233/why-does-my-view-jump-when-setting-the-layer-anchorpoint-in-an-animation-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!