Уведомление о завершении анимации панорамирования NSScrubber - PullRequest
0 голосов
/ 20 марта 2019

Элемент управления 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 NSView или NSScrollView не отображаютсяЯ не уверен, запрашиваю ли я правильный объект, чтобы добраться до нужного NSAnimation.

Попробуйте 3

Я также попробовал хакерский способ сделать это на конце кода манипуляцииНапрасно

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

Обработчик завершения вызывается почти сразу, за до инерционная прокрутка прекращается: (

Спросить

Есть ли в любом случае знатькогда заканчивается анимация жеста панорамирования скребка?

1 Ответ

0 голосов
/ 30 марта 2019

Наконец-то я нашел способ зарегистрировать обратный вызов для окончания анимации прокрутки жестом панорамирования. Сначала мы должны получить представление прокрутки внутри скруббера:

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

Спасибо за этот ответ за показ этого подхода.

...