1

NSCollectionViewウィンドウをスクロールすると、が視覚的にNSCollectionViewItem壊れてしまうという小さな刺激があります。

分割の速度は、スクロールの速度によって異なります。たとえば、ゆっくりスクロールすると、分裂がより頻繁に発生します。高速スクロールはそれほど多くありません。問題は、NSCollectionViewItem私が使用しているカスタムNSViewが表示可能なフレームの境界を越える場合にあるようです。

私のNSView(のカスタムビューNSCollectionViewItem)には、非常に単純な描画アルゴリズムがあります。複雑すぎることはありません。

基本的に、drawRectメソッドのdirtyRect内にフレームを作成し、その中にいくつかのフレームを作成します。

-(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];
}

コードの前後でフォーカスをロックして解放し、グラフィックスコンテキストを設定して復元しようとしましたが、いずれも問題を解決していないようです。

私はSnowLeopardを使用していますが、それが違いを生むとは思いません。

ソリューションの更新

ここに興味のある人は、NSResponderが推奨する問題の解決策です。私は、指摘されたように、間違ったことを行う方法にmOuterFrame基づいてイニシャルを作成していました。からのクイックチェンジ:drawRect:dirtyRect

NSRect mOuterFrame = NSMakeRect(dirtyRect.origin.x, dirtyRect.origin.y, 104, 94);

0ベースの起点へ:

NSRect mOuterFrame = NSMakeRect(0, 0, 104, 94);

上記のコード変更はそれ自体で問題を解決するのに十分でしたが、提案されたように、私は長方形のみを使用しているので、コードの効率も微調整しました。2ピクセルの線を取得するには、変更を追加する必要がありました。新しい方法:

-(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];
}
4

1 に答える 1

1

私が最初に気付いたのは、代わりにNSFrameRect()とNSRectFill()を使用するだけで、一連のパスを作成しているため、上記のコードはかなり無駄であるということです。

次に、描画するもののジオメトリは、-drawRect:に渡される長方形に依存するべきではありません。この長方形は、更新する領域を示しているだけなので、ビューが複雑な場合に何を描画するかをより効率的に決定できます。

于 2009-11-19T04:33:51.130 に答える