NSScrubber平移动画结束通知

时间:2019-03-20 15:08:53

标签: objective-c macos appkit caanimation nstouchbar

特定于触摸栏的NSScrubber控件在平移手势上会惯性滚动。我想通知该动画即将执行某些功能。

尝试1

NSScrubberDelegate有一个我实现的- didFinishInteractingWithScrubber:方法。但是,在我停止直接操纵洗涤器后不久(将手指从触摸栏上抬起),我得到了回叫,但是由于惯性,滚动仍然继续发生。被选择的最后一项不是调用此委托方法时的那一项。

尝试2

进一步挖掘,我遇到了NSAnimation。尽管没有清楚记录,但我发现洗涤器也是NSAnimatablePropertyContainer,因为其selectedIndex属性文档指出,洗涤器可以通过动画代理进行动画选择:scrubber.animator.selectedIndex = i。通过这种方式,假定,用于平滑平移的动画属性是boundsOrigin,我尝试对其进行查询。

这样做我可以得到一个CAAnimation

CAAnimation* a = [NSScrubber defaultAnimationForKey:@"boundsOrigin"];
// returns the same pointer value as above
// a = [myScrubber animationForKey:@"boundsOrigin"];
a.delegate = self;

...

- (void)animationDidStop:(CAAnimation *)anim
                finished:(BOOL)flag {
    if (flag == YES)
        NSLog(@"Animation ended!\n");
}

我得到a的有效指针值。但是,我收到了许多animationDidStop的电话,他们所有人都有flag = YES;当洗涤器滚动时,我不断收到这些呼叫,当滚动停止时,呼叫停止。这感觉与我想要的最接近,但是我不知道为什么动画结束时会有这么多来电而不是一个。

由于未公开NSScrubber的{​​{1}}或NSView,因此不确定是否要查询正确的对象才能到达正确的NSScrollView

尝试3

我也尝试了在操作结束代码上徒劳地执行此操作的方法

NSAnimation

完成处理程序几乎立即被调用,之前惯性滚动停止:(

反正还有什么知道洗涤器的平移惯性动画何时结束的吗?

1 个答案:

答案 0 :(得分:0)

我终于找到了一种为平移手势的惯性滚动动画结束注册回调的方法。首先,我们必须在洗涤器内部获取滚动视图:

- (NSScrollView*) getScrollViewForScrubber:(NSScrubber*) scrubber {
    NSScrollView* sv = nil;
    for (NSView* v in  scrubber.subviews) {
        if ([v isKindOfClass:[NSScrollView class]])
            sv = (NSScrollView*) v;
            break;
    }
    return sv;
}

现在,与其他任何滚动视图一样,该视图也具有NSScrollViewDidEndLiveScrollNotification。使用通知中心注册回调!

NSScrollView *sv = [self getScrollViewForScrubber:myScrubber];
// register for NSScrollViewWillStartLiveScrollNotification if start is also needed
[[NSNotificationCenter defaultCenter] addObserverForName:NSScrollViewDidEndLiveScrollNotification
                                                  object:sv
                                                   queue:nil
                                              usingBlock:^(NSNotification * _Nonnull note) {
                                                  NSLog(@"Scroll complete");
                                              }];