CAD无效后CADisplayLink无法停止

时间:2016-01-03 17:54:46

标签: ios cadisplaylink

我有两个UIButton,第一个按钮会触发CustomeView' - beginAnimation,另一个按钮会触发- endAnimation。当我快速按下这两个按钮时,就像begin -> end -> begin -> end -> begin -> end一样,我发现CADisplayLink无法停止。更重要的是,- rotate的点火率超过60fps,变为60 -> 120 -> 180,就像我的主RunLoop中有多个CADisplaylink一样,所以无论如何要解决它吗?我需要在视图的alpha变为零之前保持CADisplaylink运行,因此我将[self.displayLink invalidate];放在完成块中,这可能会导致此问题吗?

@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
{
    // ....
}

1 个答案:

答案 0 :(得分: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];
        }];
    }
}