2015-03-05 5 views
0

Я пишу пользовательский интерфейс Cocoa и вызываю NSView's scrollRectToVisible в течение короткого промежутка времени в результате того, что пользователь удерживает определенный ключ (и, следовательно, повторно запускает события на основная очередь).Как избежать асинхронного характера scrollToVisibleRect, вызывающего периодические проблемы с синхронизацией

Через каротаж я вижу, что следующие события keyDown() срабатывают до scrollRectToVisible, завершив предварительную замену visibleRect. Это приводит к тому, что последующий scrollRectToVisible вызывается с неправильными входами (а именно с неправильным запуском visibleRect) и ведет к нечувствительному поведению пользовательского интерфейса. Это происходит примерно в 50% случаев, которые, как я полагаю, следует ожидать, связанные с асинхронной проблемой.

Как я могу обратиться к этому вопросу?

Один из способов, которым я могу представить, - как-то превратить scrollRectToVisible в синхронный вызов. Проблема в том, что это API AppKit, и метод немедленно возвращается с логическим указанием, будет ли он прокручиваться или нет.

+0

Вы используете собственный 'NSTimer' для управления вызовами? – mikeD

+0

@mikeD Нет. Каждое последующее событие 'keyDown()' запускает 'scrollRectToVisible' последовательным образом. События 'keyDown()' запускаются буквально, просто удерживая один ключ на клавиатуре. – Sam

+0

Вы пытались переопределить метод NSView '- keyDown:' на ваш взгляд? – mikeD

ответ

0

Попробуйте поместить код в поле зрения, которое соответствует -keyDown:.

В этом примере управляет прокруткой с помощью таймера вместо повторных ключевых слов, удерживающих клавишу. Я не мог получить нежелательное поведение в пользовательском интерфейсе, поэтому я не знаю, поможет ли это.

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

 Смежные вопросы

  • Нет связанных вопросов^_^