Мне нужно перерисовать часть некоторого NSView.NSView setNeedDisplay: rect вызывает перерисовку большей площади, чем необходимо
- (IBAction)onUpdateView:(id)sender
{
NSRect updatedRect = ... // Redraw updated area only.
[self.view setNeedsDisplayInRect:updatedRect];
}
Когда я использую это простое и очевидное решение, Quartz Debug подчеркивает перерисовки гораздо больших областей - до всей площади зрения.
Я заметил, что если вызов [NSView setNeedsDisplayInRect] откладывается до следующего цикла цикла выполнения, или я просто сделать [runloop runUntilDate: +0], проблема исчезает:
- (IBAction)onUpdate:(id)sender
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self setNeedsDisplayInRect:updatedRect];
});
}
или
- (IBAction)onUpdateAndRunLoop:(id)sender
{
[self.view setNeedsDisplayInRect:updatedRect];
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0]]; // EEW
}
но если setNeedsDisplayInRect вызывается в обработчике MouseDown, он работает без всего этого повозка, запряженная волами:
-(void)mouseUp:(NSEvent*)event
{
NSPoint p = [self convertPoint:[event locationInWindow] fromView:nil];
int size = 100;
[self setNeedsDisplayInRect:NSMakeRect(p.x-size/2, p.y-size/2, size, size)];
}
Что происходит и что делать?
Изолированный Xcode проект для этой проблемы здесь: http://beta.kalinsky.ru/wtf/testRedraw.tar.gz
Имеет ли этот вид вы хотите перерисовать собственный метод drawRect? Если так, вы рисуете все там или вы уважаете dirtyRect и только перерисовываете материал, который находится в этом прямоугольнике? Или, может быть, это мнение обрезается, а также выводит его внеэкранный контент? – HAS
@ ХАС: Конечно, это было мое первое подозрение. Метод drawRect в прикрепленном проекте буквально "[NSBezierPath fillRect: dirtyRect];" –
Вы нашли лучшее объяснение, чем тот, который я дал ниже в ответ и комментарии? При рисовании текст и прозрачность влияют на большую производительность. –