2

iOS アプリのビューに UIPanGestureRecognizer をアタッチしています。パン ハンドラーのコードをTouches サンプル アプリからコピーしました。ジェスチャが開始すると、私のコード:

  • 元のアンカー ポイントと中心を記録します。
  • 次のように、アンカー ポイントと中心をユーザーの指の周りに変更します。

    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;
    

ジェスチャが進行するにつれて、パン ハンドラーは指の動きを追跡するために中心を継続的に変更します。ここまでは順調ですね。

ユーザーが手放したら、ビューをアニメーション化して元の開始点に戻します。これを行うコードは次のようになります。

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

そして、それはビューをアニメーション化して元の開始点に戻します。ただし、アニメーションが開始する前に、ビューは UI の別の場所にジャンプします。IOW、手放すとジャンプし、元の場所にアニメーションで戻ります。

おそらく、アニメーションの外側にアンカーポイントと中心を設定する必要があると思いました。おそらく、ジェスチャーが始まるときのように、中心をスーパービューの場所に設定する必要があると思いましたが、それは違いはないようです.

ここで何が欠けていますか?ユーザーが手放したときにジャンプを防ぐにはどうすればよいですか?

4

1 に答える 1

11

あなたがやっていることを試してみなくても、2つの問題があると思います:

アンカー ポイントを変更すると、ビュー/レイヤーの位置が変更されます。位置を変更せずにアンカー ポイントを変更するには、次のようなヘルパーを使用できます。

-(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;
}

(私は自分のプロジェクトでそれを使用しています。ここにあります:Changing my CALayer's anchorPoint moves the view

アニメーションは、アンカー ポイントを元の値に戻します。 上記のヘルパーを使用して、アンカー ポイントをリセットする必要があります。これにより、アンカーを変更してもビューが移動しないことが保証されます。これはアニメーションの外で行う必要があります。その後、アニメーション ブロックを使用してビューの中心を変更し、必要な場所にアニメーション化します。

于 2012-05-22T11:02:43.927 に答える