0

ゴール

UI Dynamics プル アニメーション/動作を複製しようとしています。私はそれをドラッグするためUIPanGestureRecognizerに自分でセットアップしました。UIViewドラッグが発生すると、タッチポイントをUIView.layer.anchorPoint中心に回転できるようにタッチポイントを設定します。ドラッグ中は、タッチ速度の方向を確認して、CGAffineTransformRotate時計回りまたは反時計回りに適用します。これが私が話していることです。

ここに画像の説明を入力

問題

ドラッグして回転を適用すると、アニメーションがスムーズに発生せず、UIView がちらつきます (ビューの複数のトレースが短いインスタンスで表示されます)。動画撮影は30fpsな​​のでちらつきはあまり目立ちません。私の説明がそれを明確にしていることを願っています。

私のView Controllerのソースコードは以下の通りです。iOS5.0以降で試しています

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UIView *animationView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
    animationView.layer.backgroundColor = [UIColor redColor].CGColor;
    animationView.layer.shouldRasterize = YES; // Does not help :(
    animationView.autoresizingMask = UIViewAutoresizingNone; // Does not help :(

    [self.view addSubview:animationView];

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
    [animationView addGestureRecognizer:pan];
    [animationView release];
    [pan release];
}

- (void) pan:(UIPanGestureRecognizer*) gesture {

    if(gesture.state==UIGestureRecognizerStateBegan) {
        CGPoint anchor = [gesture locationInView:gesture.view];

        gesture.view.layer.anchorPoint = CGPointMake(anchor.x/gesture.view.bounds.size.width,
                                                     anchor.y/gesture.view.bounds.size.height);

        gesture.view.center = CGPointMake(anchor.x/gesture.view.bounds.size.width,
                                          anchor.y/gesture.view.bounds.size.height);
    }
    else if(gesture.state==UIGestureRecognizerStateChanged) {
        CGPoint point1 = [gesture locationInView:self.view];
        gesture.view.center=point1;

        CGPoint velocity = [gesture velocityInView:gesture.view];
        if(velocity.x > 0)
        {
            // Dragged right
            if(velocity.y > 0) {
                // Dragged down
                // counter clock
                CGFloat angle = -0.2;
                gesture.view.transform = CGAffineTransformRotate(gesture.view.transform, angle);
            }
            else {
                // Dragged up
                // clock
                CGFloat angle = 0.2;
                gesture.view.transform = CGAffineTransformRotate(gesture.view.transform, angle);
            }
        }
        else
        {
            // Dragged left
            if(velocity.y > 0) {
                // Dragged down
                // clock
                CGFloat angle = 0.2;
                gesture.view.transform = CGAffineTransformRotate(gesture.view.transform, angle);
            }
            else {
                // Dragged up
                // counter clock
                CGFloat angle = -0.2;
                gesture.view.transform = CGAffineTransformRotate(gesture.view.transform, angle);
            }
        }
    }
}

CATransform3DMakeRotation (angle, 0.0f, 0.0f, 1.0f)ビューの代わりにレイヤーに適用しようとしましたCGAffineTransformRotate。しかし、ちらつきはまだ発生します。この問題の理由はありますか? 同じ結果を達成するための他のアプローチについてのアドバイスを歓迎します。

4

1 に答える 1

-1

この問題を解決するために真剣に考えた後、私はそれが些細な間違いであることに気付きました。ちらつきは、ドラグ方向のわずかな変化でも回転させているためです。これを解決するために、回転を行う前にピクセル変更の任意のマージンを想定しました。

問題を解決した変更されたコードは次のとおりです

- (void) pan:(UIPanGestureRecognizer*) gesture {

    if(gesture.state==UIGestureRecognizerStateBegan) {
        CGPoint anchor = [gesture locationInView:gesture.view];
        gesture.view.layer.anchorPoint = CGPointMake(anchor.x/gesture.view.bounds.size.width,
                                                     anchor.y/gesture.view.bounds.size.height);
    }
    else if(gesture.state==UIGestureRecognizerStateChanged) {
        CGPoint point1 = [gesture locationInView:self.view];
        gesture.view.layer.position=point1;

        CGPoint velocity = [gesture velocityInView:gesture.view];
        CGFloat angle = 0.0;
        if(velocity.x > self.view.bounds.size.width*0.15)
        {
            // Dragged right
            if(velocity.y > self.view.bounds.size.height*0.02) {
                // Dragged down
                // counter clock
                angle = -0.05;
            }
            else if (velocity.y < -self.view.bounds.size.height*0.02) {
                // Dragged up
                // clock
                angle = 0.05;
            }
        }
        else if (velocity.x < -self.view.bounds.size.width*0.15)
        {
            // Dragged left
            if(velocity.y > self.view.bounds.size.height*0.02) {
                // Dragged down
                // clock
                angle = 0.05;
            }
            else if (velocity.y < -self.view.bounds.size.height*0.02) {
                // Dragged up
                // counter clock
                angle = -0.05;
            }
        }
        [self applyRotationToView:gesture.view byAngle:angle];
    }
}

- (void) applyRotationToView:(UIView*)rotationView byAngle:(CGFloat)angle {
    rotationView.transform = CGAffineTransformRotate(rotationView.transform, angle);
}

アニメーションはまだ期待するほど滑らかではありませんが、煩わしいちらつきを減らすことができました。

于 2013-06-20T07:06:30.870 に答える