如何在不重绘整个视图的情况下更新 NSView 的一部分

Posted

技术标签:

【中文标题】如何在不重绘整个视图的情况下更新 NSView 的一部分【英文标题】:How to update a section of an NSView without redrawing the whole view 【发布时间】:2009-12-23 13:35:42 【问题描述】:

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

     [self setsetNeedsDisplay:YES];

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

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

但似乎 drawRect 会破坏所有其他先前绘制的路径并仅重绘被剪裁的路径。

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

谢谢, 卢卡

【问题讨论】:

【参考方案1】:

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

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

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

【讨论】:

嗨,好的,我可以传递类似:[self setNeedsDisplayInRect: [path bounds]]... 即使它不是很舒服,因为我不知道那个 NSRect 上有多少路径...但我可以尝试重新考虑该功能。相反,我如何利用 NSTrackingArea 并不是很清楚。目前我已经有了一个覆盖整个 NSView 的 trackingarea,但是我认为生成的事件仍然发送到 mouseMoved 函数,不是吗?谢谢,卢卡 您的mouseMoved: 方法将由NSEvent 实例触发,您向事件发送-trackingArea 消息以获取对触发它的NSTrackingArea 实例的引用,然后询问它的矩形。【参考方案2】:

我认为我以更快的方式解决了问题,因为我不知道矩形中存在哪些路径我想避免通过所有路径循环。幸运的是,我的路径不会经常更改,因此我可以将所有路径缓存在 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];

【讨论】:

以上是关于如何在不重绘整个视图的情况下更新 NSView 的一部分的主要内容,如果未能解决你的问题,请参考以下文章

NSTableView 在特定条件下不重绘

如何在不重定向的情况下从数据库实时更新赞成票和反对票数?

UICollectionView 不重绘

Android:自定义视图缩放/捏合

如何在不重定向原始 URL 的情况下获取短 URL 服务的信息或实际信息

如何在不像 Whatsapp 那样遮挡整个屏幕的情况下禁用表格视图?