Перерисовка NSCollectionView на Scroll вызывает разрушение графики - PullRequest
1 голос
/ 18 ноября 2009

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

Скорость разделения зависит от скорости прокрутки. Например, если я прокручиваю медленно, разрыв происходит чаще. Быстрая прокрутка меньше так. Кажется, что проблема в том, что пользовательский 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 - не то, чтобы я думал, что это имеет значение.

Обновление решения

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

1 голос
/ 19 ноября 2009

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

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

...