2

パンジェスチャに基づいてビューを移動するために必要なのはそれだけです。問題は、Apple Maps のようにすぐには起こらないことです。指を 1 点に置いて任意の方向にすばやく移動すると、ビューが遅れて移動します。つまり、私が指を置いた点であり、それは私が望んでいないことです。

シミュレーターでは問題なく動作するため、ハードウェアの制限により不可能な場合があります。または、私が知らないより良い方法があるかもしれません。

ありがとうございました。


- (IBAction)pan:(UIPanGestureRecognizer *)sender 
{
    CGPoint center = [sender locationInView:sender.view];
    self.myView.center = center; 
}
4

2 に答える 2

6

私が最初に答えたとき、私は、ドラッグされているビューについて何か複雑なことがあると思っていました(たとえば、大きなCALayer影は計算コストがかかる可能性があります)。したがって、以下の私の元の答え。しかし、その後のコメント交換で、ボタンの1つに脈打つアニメーションがあることが発見されました。これは、問題である可能性が高いです。ドラッグのパフォーマンスが許容できない場合は、ビューのドラッグ中にアニメーションを一時停止する必要があります。したがって:

#import <QuartzCore/QuartzCore.h>

- (IBAction)pan:(UIPanGestureRecognizer *)gesture
{
    static CGPoint originalCenter;

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        originalCenter = gesture.view.center;
        [self pauseLayer:gesture.view.layer];
    }
    else if (gesture.state == UIGestureRecognizerStateChanged)
    {
        CGPoint translate = [gesture translationInView:gesture.view.superview];
        gesture.view.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y);
    }
    else if (gesture.state == UIGestureRecognizerStateEnded ||
             gesture.state == UIGestureRecognizerStateFailed ||
             gesture.state == UIGestureRecognizerStateCancelled)
    {
        [self resumeLayer:gesture.view.layer];
    }
}

-(void)pauseLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
    layer.speed = 0.0;
    layer.timeOffset = pausedTime;
}

-(void)resumeLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer timeOffset];
    layer.speed = 1.0;
    layer.timeOffset = 0.0;
    layer.beginTime = 0.0;
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    layer.beginTime = timeSincePause;
}

明らかに、これは以下で説明する画像のラスタライズと組み合わせることができますが、最初に上記のようにアニメーションを一時停止してみます。


元の答え:

ドラッグされているビューがまったく複雑な場合は、ラスタライズしてみてください。

  1. QuartzCore.frameworkターゲットの「ライブラリとバイナリをリンクする」設定に追加します。

  2. 次に、ソースを調整して、それに応じてラスタライズします。

そのような:

#import <QuartzCore/QuartzCore.h>

- (IBAction)pan:(UIPanGestureRecognizer *)gesture
{
    static CGPoint originalCenter;

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        originalCenter = gesture.view.center;
        gesture.view.layer.shouldRasterize = YES;
    }
    if (gesture.state == UIGestureRecognizerStateChanged)
    {
        CGPoint translate = [gesture translationInView:gesture.view.superview];
        gesture.view.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y);
    }
    if (gesture.state == UIGestureRecognizerStateEnded ||
        gesture.state == UIGestureRecognizerStateFailed ||
        gesture.state == UIGestureRecognizerStateCancelled)
    {
        gesture.view.layer.shouldRasterize = NO;
    }
}

余談originalCenterですが、このコードのように保存することをお勧めします。そうすれば、ビューを中心から少しずらしてドラッグしても、ぎこちなくジャンプすることはありません。

于 2013-01-10T19:37:06.953 に答える
1

中心点に新しい値を設定するときに、アニメーションを無効にしてみてください。

- (IBAction)pan:(UIPanGestureRecognizer *)sender 
{
    CGPoint center = [sender locationInView:sender.view];
    [CATransaction begin];
    [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
    self.myView.center = center; 
    [CATransaction commit];
}

それが助けになるなら、あなたはより速いアニメーションでそれを滑らかにすることを試みることができます。

ここで説明するように、アニメーションを無効にすることもできます: iOS4+でUIViewアニメーションを明示的に無効にする

まもなく:

- (IBAction)pan:(UIPanGestureRecognizer *)sender 
{
    CGPoint center = [sender locationInView:sender.view];
    [UIView setAnimationsEnabled:NO];
    self.myView.center = center; 
    [UIView setAnimationsEnabled:YES];
}

再配置中にすべてのアニメーションを無効にできたら、それはハードウェアとコードの速度次第です。

于 2013-01-10T19:50:44.240 に答える