1

我在NSCollectionView中遇到了一個小問題,當我滾動窗口時,NSCollectionViewItem的視覺被分解了。滾動滾動導致NSCollectionView導致圖形崩潰

分手率取決於滾動的比率。例如,如果我慢慢滾動,分手就會更頻繁地發生。快速滾動更少。看來問題在於當我使用的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]; 
} 

我試圖鎖定焦點和釋放之前和代碼之後以及設置圖形上下文並恢復它 - 這似乎無法解決問題。

我正在使用雪豹 - 不是我認爲這有所作爲。

解決方案更新

任何有興趣在這裏是解決問題的建議NSResponder類。我正在根據drawRect:方法dirtyRect創建初始mOuterFrame,正如指出的那樣,這是不正確的事情。快速變化從:

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'。 – 2009-11-19 08:13:05

+0

NSResponder - 謝謝。這解決了這個問題(不基於dirtyRect的初始外框)。我還調整了使用NSFrameRect更高效的代碼。謝謝! – Hooligancat 2009-11-19 22:39:19