如何避免scrollToVisible Rect的异步性导致间歇性计时问题

时间:2015-03-05 10:34:17

标签: cocoa nsview appkit nsscrollview

我正在编写一个Cocoa UI,并且由于用户按住某个键(因此在主队列上反复触发事件)而在短时间内重复调用NSView's scrollRectToVisible

通过记录,我可以看到在keyDown()完成其先前更改scrollRectToVisible之前,连续的visibleRect事件正在触发。这导致随后的scrollRectToVisible被错误的输入调用(即错误的启动visibleRect),并导致非敏感的UI行为。这种情况发生在大约50%的时间,我猜这是处理异步问题的预期。

我该如何解决这个问题?

我能想到的一种方法是以某种方式将scrollRectToVisible转变为同步调用。问题是它是一个AppKit API,该方法立即返回一个布尔值,指示它是否要滚动。

1 个答案:

答案 0 :(得分:0)

尝试将代码放在响应-keyDown:的视图中。

此示例使用计时器控制滚动,而不是使用重复的keyDowns来控制滚动。 我无法获得UI不需要的行为,因此我不知道这是否会有所帮助。

- (BOOL)acceptsFirstResponder {
    return YES;
}
- (BOOL)canBecomeKeyView {
    return YES;
}
- (void)keyDown:(NSEvent *)theEvent {
    if (timer == nil) {
        timer = [NSTimer scheduledTimerWithTimeInterval:0.01
                                                 target:self
                                               selector:@selector(doScroll:)
                                               userInfo:nil
                                                repeats:YES];
    }
    NSLog(@"event %@ with Timer%@", theEvent, timer);
}
- (void)keyUp:(NSEvent *)theEvent {
    [timer invalidate];
    timer = nil;
    NSLog(@"keyUp timer:%@", timer);
    NSLog(@"event %@", theEvent);
}
- (void)doScroll:theTimer {
    NSEvent * current = [NSApp currentEvent]; //use this to parse
    NSLog(@"current press %@", current);
    [self scrollRectToVisible:NSMakeRect(self.visibleRect.origin.x + 10,
                                         self.visibleRect.origin.y + 10,
                                         self.bounds.size.width,
                                         self.bounds.size.height)];
}