Перераспределение NSCollectionView на прокрутке вызывает распад графики
-
20-09-2019 - |
Вопрос
У меня незначительное раздражение в NSCollectionView
в которой NSCollectionViewItem
Разбивается визуально, когда я прокручиваю окно.
Скорость разрыва зависит от скорости прокрутки. Например, если я медленно прокручиваю, разрыв происходит чаще. Быстрая прокрутка меньше. Похоже, что проблема в том, когда пользовательский NSView NSCollectionViewItem
Я использую кресты границу просматривающейся рамки.
Мой nsview (пользовательский вид NSCollectionViewItem
) имеет очень простой алгоритм рисования - ничего слишком сложного.
По сути, я создаю кадр в грязном образе метода натяжения и создаю несколько кадров внутри этого:
-(void)drawRect:(NSRect)dirtyRect
{
NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);
NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);
NSBezierPath * mOuterFramePath = [NSBezierPath bezierPathWithRect:mOuterFrame];
NSBezierPath * mSelectedFramePath = [NSBezierPath bezierPathWithRect:mSelectedFrame];
NSBezierPath * mRedFramePath = [NSBezierPath bezierPathWithRect:mRedFrame];
NSBezierPath * mInnerFramePath = [NSBezierPath bezierPathWithRect:mInnerFrame];
[mainBackgroundColor set];
[mOuterFramePath fill];
if (selected)
[[NSColor yellowColor] set];
else
[mainBackgroundColor set];
[mSelectedFramePath fill];
if (isRedBorder)
[[NSColor redColor] set];
else
[mainBackgroundColor set];
[mRedFramePath fill];
[[NSColor blackColor] set];
[mInnerFramePath fill];
}
Я пытался заблокировать фокус и выпустить до и после кода, а также установить графический контекст и восстановить его - ни один из которых, кажется, не решает проблему.
Я использую Snow Leopard - не то, что я думаю, что это имеет значение.
Обновление решения
Для всех, кто заинтересован здесь, является решением проблемы, рекомендованной NSResponder. Я создавал начальный mOuterFrame
на основе drawRect:
методы dirtyRect
что, как отмечалось, было неверным, что нужно сделать. Быстрое изменение от:
NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);
В 0 -м точке происхождения:
NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);
Я также настроил эффективность кода, будучи таким, как я использую только прямоугольники, как предполагалось, хотя изменения кода было достаточно, чтобы сама по себе решить проблему. Я должен был добавить изменение, чтобы получить линию двух пикселей. Новый метод:
-(void)drawRect:(NSRect)dirtyRect
{
NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);
NSRect mSelectedFrame = NSInsetRect(mOuterFrame, 2, 2);
NSRect mRedFrame = NSInsetRect(mSelectedFrame, 2, 2);
NSRect mInnerFrame = NSInsetRect(mRedFrame, 2, 2);
[NSBezierPath setDefaultLineWidth:2.0];
[mainBackgroundColor set];
[NSBezierPath strokeRect:mOuterFrame];
if (selected)
[[NSColor yellowColor] set];
else
[mainBackgroundColor set];
[NSBezierPath strokeRect:mSelectedFrame];
if (isRedBorder)
[[NSColor redColor] set];
else
[mainBackgroundColor set];
[NSBezierPath strokeRect:mRedFrame];
[[NSColor blackColor] set];
[NSBezierPath strokeRect:mInnerFrame];
}
Решение
Во -первых, я заметил, что ваш код выше довольно расточительна, поскольку вы создаете кучу путей, когда вы можете просто использовать nsframerect () и nsrectfill ().
Во -вторых, геометрия того, что вы рисуете, не должна зависеть от прямоугольника, передаваемого в -монте:. Этот прямоугольник просто рассказывает вам, какая область для обновления, поэтому вы можете быть более эффективным, решая, что нарисовать, если ваш взгляд является сложным.