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