8

我正在为视图制作动画(通过显示它),之后我需要发布通知(一旦动画完成)。无论应用程序的设计方式如何,当视图隐藏时(通过动画)会发出另一个通知。所以基本上我有一个“showView”和一个“hideView”方法。每个人都这样做:

    [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
      [context setDuration: 0.25];

      [[myView animator] setAlphaValue: 0];
    } completionHandler:^{
       // post notification now
    }];

问题是在后台的另一个线程中,我有一个定期计时器,它执行“健全性检查”以查看是否需要隐藏视图(如果不需要)。这是一种激进的方法,但很有必要,因为应用程序的许多组件都响应不同的事件和场景。由于这个原因,我有时会得到一个“竞争条件”,用户点击了“showView”,但同时我们的一个线程觉得应该立即隐藏视图。

当两者都在主线程上发布通知时,应用程序会无限期地挂在 SpinLock 中。如果我能够确定上面的动画块是否被“取消”(即在同一视图上执行的另一个动画块),我可以完全避免这种情况。在这种情况下,我不会发布通知,这样就不会强制进行检查。

长话短说:我需要能够检查动画成功结束后是否调用了“completionHandler”或者它是否被取消。我知道在 iOS 中这是可能的,但我在 OS X 中找不到任何方法。请帮忙。

4

1 回答 1

1

我遇到了类似的问题。我通过使用currentAnimationUUID实例变量解决了它。

NSUUID *animationUUID = [[NSUUID alloc] init];
self.currentAnimationUUID = animationUUID;

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
    // set properties to animate
} completionHandler:^{
    BOOL isCancelled = ![self.currentAnimationUUID isEqual:animationUUID];
    if (isCancelled) {
        return;
    }

    self.currentAnimationUUID = nil;

    // do stuff
}];

斯威夫特版本:

let animationUUID = UUID()
currentAnimationUUID = animationUUID

NSAnimationContext.runAnimationGroup({ context in
    // set properties to animate
}, completionHandler: {
    let isCancelled = self.currentAnimationUUID != animationUUID
    guard !isCancelled else {
        return
    }

    self.currentAnimationUUID = nil

    // do stuff
})
于 2018-12-28T21:30:47.727 回答