1

У меня есть незначительный раздражитель в NSCollectionView, в котором NSCollectionViewItem разваливается визуально при прокрутке окна.Повторное рисование NSCollectionView на прокрутке Причины разрыва графики

Скорость разрыва зависит от скорости прокрутки. Например, если я медленно прокручиваю, распад происходит чаще. Быстрая прокрутка меньше. Похоже, что проблема заключается в том, что пользовательский NSView используемого мной NSCollectionViewItem пересекает границу видимого фрейма.

Мой NSView (пользовательский вид NSCollectionViewItem) имеет очень простой алгоритм рисования - ничего сложного.

существу создать рамку внутри dirtyRect метода DrawRect и создать несколько кадров в том, что:

-(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 - не то, что я думаю, что это имеет значение.

Решение Update

Для тех, кто заинтересован здесь является решение проблемы в соответствии с рекомендациями 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]; 
} 

ответ

1

Первое, что я заметил, что ваш код выше довольно расточительно, так как вы создаете кучу путей, когда вы могли бы просто использовать NSFrameRect() и NSRectFill() вместо этого.

Во-вторых, геометрия того, что вы рисуете, не должна зависеть от прямоугольника, переданного на -drawRect :. Этот прямоугольник просто сообщает вам, что область обновления, так что вы можете быть более эффективными при принятии решения о том, что делать, если ваш взгляд является сложным.

+0

Я думаю, вы имеете в виду 'NSFrameRect', а не' NSDrawRect'. –

+0

NSResponder - спасибо. Это устранило проблему (не основывая исходный внешний фрейм на dirtyRect). Я также модифицировал код, чтобы быть более эффективным с использованием NSFrameRect. Благодаря! – Hooligancat