NSScrubber泛动画结束通知

问题描述 投票:0回答:1

触摸栏特定的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;当擦洗器滚动时,我不停地接收这些呼叫,当滚动停止时,呼叫停止。这感觉最接近我想要的但是我不知道为什么在动画结束时会有这么多来电而不是一个。

由于NSScrubberNSViewNSScrollView没有暴露,我不确定我是否正在查询正确的物体到达正确的NSAnimation

试试3

我也尝试了在操作结束代码上徒劳无功的hacky路线

-(void)didFinishInteractingWithScrubber:(NSScrubber *)scrubber {
    NSLog(@"Manipulation ended\n");
    NSAnimationContext*c = NSAnimationContext.currentContext;
    [c setCompletionHandler:^{
        NSLog(@"Inertial scrolling stopped!\n");
    }];
}

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

无论如何要知道洗涤器的平移手势惯性动画何时结束?

objective-c macos appkit caanimation nstouchbar
1个回答
0
投票

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

- (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");
                                              }];

感谢this answer展示这种方法。

© www.soinside.com 2019 - 2024. All rights reserved.