0

我有两个UIButton,第一个按钮将触发 CustomeView - beginAnimation,另一个按钮将触发- endAnimation. 当我依次快速按下这两个按钮时begin -> end -> begin -> end -> begin -> end,我发现CADisplayLink停不下来。更何况 的- rotate射速超过 60fps,变成60 -> 120 -> 180了 ,就像CADisplaylink我的主 RunLoop 里有不止一个,那么有没有办法修复它?而且我需要CADisplaylink在view的alpha归零之前保持运行,所以我把它[self.displayLink invalidate];放在了completion block中,可能会导致这个问题?</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当你完成它时设置为零。

- (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 回答