Глюки рисования какао, когда окно проигрывает, а затем восстанавливает основной статус

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

Вот пример:

Вид нарисован правильноВид, нарисованный с ошибкой

Заметили странную темную линию слева от фона представления? Это нарисовано даже без подвидов в представлении. Я получаю другие подобные ошибки в некоторых других моих представлениях.

Вот код, который рисует:

void EDDrawGlossEffectInRect(NSRect dirtyRect) {
    NSRect topRect, bottomRect;
    NSDivideRect(dirtyRect, &topRect, &bottomRect, (dirtyRect.size.height / 2), NSMaxYEdge);

    [EDLightChromeColor set];
    NSRectFill(topRect);

    [EDMidChromeColor set];
    NSRectFill(bottomRect);
}

и

-(void)drawRect:(NSRect)dirtyRect {
    EDDrawGlossEffectInRect(dirtyRect);

    NSBezierPath *path = [NSBezierPath bezierPath];
    [path setLineWidth:1.0];

    NSPoint startPoint = {0, dirtyRect.size.height};
    NSPoint endPoint = {dirtyRect.size.width, dirtyRect.size.height};

    [path moveToPoint:startPoint];
    [path lineToPoint:endPoint];

    [[NSColor colorWithCalibratedWhite:0.7 alpha:1] set];

    [path stroke];
}

Представление создается программно, а не с помощью Interface Builder, который я не использую для этого проекта.


person d11wtq    schedule 13.12.2010    source источник


Ответы (1)


dirtyRect не обязательно будет покрывать видимый прямоугольник вашего представления, поэтому вы можете захотеть увидеть, какая часть границ вашего представления пересекается с dirtyRect, и просто перерисовать это. В противном случае просто перерисуйте границы представления. Изменение размера окна может привести к тому, что все границы будут грязными (обычно), поэтому, вероятно, в этот момент вы видите полную перерисовку.

person Ian Baird    schedule 13.12.2010
comment
Я совершенно не осознавал этого, и я думаю, это имеет смысл, если у вас есть большой вид, который обрезан / обрезан и т. д. Рисование фрагмента этого простого вида было бы болезненным и, вероятно, чрезмерным, поэтому я просто изменился, чтобы нарисовать весь границ и вы правы, ошибка исчезла. Спасибо. - person d11wtq; 13.12.2010
comment
Если рисование становится горячей точкой при профилировании вашего приложения с помощью инструментов, вы можете вернуться к этому. До тех пор я бы не стал беспокоиться о преждевременной оптимизации этого метода. Пожалуйста. - person Ian Baird; 13.12.2010