Check if NSAnimationContext runAnimationGroup cancelled or succeeded

笑着哭i 提交于 2019-12-23 07:48:23

问题


I'm animating a view (by revealing it) after which I need to post a notification (once the animation completes). However the way the app's designed, there's another notification sent out when the view is hidden (via animation). So essentially I have a 'showView' and a 'hideView' method. Each do something like so:

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

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

The problem is that in another thread in the background, I have a periodic timer which performs a 'sanity check' to see if the view needs to be hidden if it's not needed. It's an aggressive approach but necessary as many components of the app respond to different events and scenarios. Due to this I at times get a 'race condition' where the user has clicked to 'showView' but at the same time one of our threads feel the view should be immediately hidden.

When both post a notification on the main thread, the app hangs indefinitely in a SpinLock. I could completely avoid this situation if I was able to figure out if the animation block above was 'cancelled' (i.e. another animation block executed on the same view). In such situations I would not post the notification, which would then not force a check.

Long story short: I need to be able to check if the 'completionHandler' was called after animation successfully ended or if it was cancelled. I know in iOS this is possible but I can't find any way to do this in OS X. Please help.


回答1:


I encountered a similar problem. I solved it by using a currentAnimationUUID instance variable.

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
}];

Swift version:

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
})


来源:https://stackoverflow.com/questions/18772798/check-if-nsanimationcontext-runanimationgroup-cancelled-or-succeeded

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!