2

我有一个 NSView,我在其中绘制了数千个 NSBezierPaths。我想在 mousemoved 事件中突出显示(更改填充颜色)选定的一个。目前我在 mouseMoved 函数中使用以下命令:

     [self setsetNeedsDisplay:YES];

这会强制调用 drawRect 来重绘每条路径。我想只重绘选定的一个。我尝试在 drawRect 函数中使用 addClip:

      NSBezierPath * path = ... //builds the path here
      [path addClip];
      [path fill];

但似乎 drawRect 破坏了所有其他先前绘制的路径,并且只重绘了被裁剪的路径。

调用drawRect时是否可以不使所有视图无效?我的意思是逐步覆盖之前视图中的内容?

谢谢,卢卡

4

2 回答 2

4

你应该使用[self setNeedsDisplayInRect:…]. 传递您想要失效的 NSRect,这将是传递给drawRect:调用的区域。

在里面drawRect:,检查传入的区域,只在该矩形内执行必要的绘制。

此外,您可能想考虑使用NSTrackingArea而不是mouseMoved:- 这些允许您设置特定的矩形来触发更新。

于 2009-12-23T13:41:54.060 回答
1

我想我以更快的方式解决了问题,因为我不知道矩形中存在哪些路径我想避免通过所有路径的循环。幸运的是,我的路径不会经常更改,因此我可以将所有路径缓存在 NSImage 中。在 mouseMoved 事件上我设置:

RefreshAfterMouseMoved = YES;

在 drawRect 函数中我放了类似的东西:

if (RefreshAfterMouseMoved) {       
    [cacheImage drawAtPoint:zero fromRect:viewRect operation:1 
                       fraction:(CGFloat)1.0];
        //redraw only the hilighted path
}
else{
    if (cacheImage) [cacheImage release];   
    cacheImage = [[NSImage alloc] initWithSize: [self bounds].size ];
    [cacheImage lockFocus];
    // draw everything here
    [cacheImage unlockFocus];
    [cacheImage drawAtPoint:zero fromRect:viewRect operation:1 
                   fraction:(CGFloat)1.0];
}

此方法可以与上面的 setNeedsDisplayInRect 方法结合使用 mousedMoved 函数:

   NSRect a, b, ab;
   a = [oldpath bounds];
   b = [newpath bounds];
   ab = NSUnionRect(a,b);
   RefreshAfterMouseMoved = YES;
   [self setNeedsDisplayInRect:ab];
于 2009-12-25T10:43:27.273 回答