0

UIButton最初のボタンは CustomeView をトリガーし- beginAnimation、もう 1 つのボタンは をトリガーします- endAnimation。この 2 つのボタンを のようにすばやく交互に押すと、停止できないことがbegin -> end -> begin -> end -> begin -> endわかりました。CADisplayLinkさらに、- rotateの連射速度は 60fps を超えており、私のメインの RunLoop に60 -> 120 -> 180複数あるように になりました。それを修正する方法はありますか? CADisplaylinkそして、ビューのアルファがゼロになる前に実行を続ける必要があるため、完了ブロックCADisplaylinkに を入れました[self.displayLink invalidate];。これがこの問題を引き起こすのではないでしょうか?</p>

@interface CustomeView : UIView
@end

@implementation CustomeView

- (void)beginAnimation // triggered by a UIButton
{
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 1.0; }];
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(rotate)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)endAnimation // triggered by another UIButton
{
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 0.0; } completion:^(BOOL finished) {
        [self.displayLink invalidate];
    }];
}

- (void)rotate
{
    // ....
}
4

1 に答える 1

0

-beginAnimation完了ブロック-endAnimationが実行される前、つまり 0.5 秒のアニメーションが終了する前に呼び出した場合、古いself.displayLinkものを新しいもので上書きします。その後、完了ブロックが実行されると、古い表示リンクではなく、新しい表示リンクが無効になります。

中間変数を使用して、self.displayLink無効にする表示リンクを保持する値を取得します。また、念のため、使いself.displayLink終わったら nil に設定してください。

- (void)beginAnimation // triggered by a UIButton
{
    [UIView animateWithDuration:0.5 animations:^{ self.alpha = 1.0; }];

    if (self.displayLink != nil) {
        // You called -beginAnimation before you called -endAnimation.
        // I'm not sure if your code is doing this or not, but if it does,
        // you need to decide how to handle it.
    } else {
        // Make a new display link.
        self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(rotate)];
        [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
}

- (void)endAnimation // triggered by another UIButton
{
    if (self.displayLink == nil) {
        // You called -endAnimation before -beginAnimation.
        // Again, you need to determine what, if anything,
        // to do in this case.
    } else {
        CADisplayLink oldDisplayLink = self.displayLink;
        self.displayLink = nil;

        [UIView animateWithDuration:0.5 animations:^{ self.alpha = 0.0; } completion:^(BOOL finished) {
            [oldDisplayLink invalidate];
        }];
    }
}
于 2016-01-03T19:45:03.227 に答える