在绘制之前要停止清除NSView drawRect? (lockFocus不再在macOS 10.14上运行)

时间:2018-12-13 10:14:46

标签: calayer nsview drawrect macos-mojave

我有一个使用两个视图的动画,我将调用lockFocus并使用[[NSGraphicsContext currentContext] graphicsPort]进入第二个NSView的图形上下文,然后绘制。直到macOS 10.14(Mojave)都可以正常工作。

在这里找到了参考: https://developer.apple.com/videos/play/wwdc2018/209/

在22:40,他们谈论已经改变的“传统”后备商店。上面的lockFocus和上下文模式在屏幕上很大,表示不再起作用。那是真的。 lockFocus()仍然有效,甚至可以为您提供正确的NSView,但是通过上下文进行的任何绘制都不再起作用。

当然,绘制视图的正确方法是通过Nsview的drawRect。因此,我重新安排了一切以实现此目的。那行得通,但是在调用drawRect之前,drawRect已经为您自动清除了“脏”区域。如果您使用setNeedsDisplayInRect:它将甚至只为您清除那些区域。但是,它还将清除由多个脏矩形组成的区域。而且,当我绘制圆形物体时,它会清除矩形区域,因此最终会导致清除过多(黑色区域):

black area is cleared

有没有办法防止drawRect清除背景?

否则,我将转而使用NSView的图层,并使用updateLayer或其他东西。

更新:我正在使用NSView层,为wantLayer和wantsUpdateLayer返回TRUE,并实现:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx

那是我做的只有

- (BOOL) wantsLayer { return YES; }
- (BOOL) wantsUpdateLayer { return NO; } 

使用setNeedsDisplayInRect:或setNeedsDisplay:

这确实使drawRect不再被调用,但是到我的drawLayer:调用时,已经发生了相同的自动背景擦除。所以我在那里没有任何进展。确实是setNeedsDisplayInRect的效果,而不是我的绘图。仅调用setNeedsDisplayInRect会导致这些擦除。

如果您设置:

- (BOOL) wantsLayer { return YES; }
- (BOOL) wantsUpdateLayer { return YES; } 

唯一被称为的是:

- (void) updateLayer

这没有为我提供绘图的上下文。

我希望:

self.layerContentsRedrawPolicy = NSViewLayerContentsRedrawNever;

NSView文档说:

  

单独保留图层的内容。切勿将图层标记为需要   显示或将视图的内容绘制到图层。这就是   开发人员创建的图层(图层托管视图)得到处理。

,它就是这么做的。它不会通知您,也不会呼叫代表。

是否可以完全控制NSView /图层的内容?

更新2019年1月27日: 我猜NSView有一个方法makeBackingLayer并非没有。实现了这一点,并且看起来似乎可以正常工作,但是屏幕上没有显示任何输出。因此是后续问题:nsview-makebackinglayer-with-calayer-subclass-displays-no-output

2 个答案:

答案 0 :(得分:1)

使用NSView BigDecimal a = new BigDecimal(5190000000L * 1.0); Output: 5190000000 lockFocus,或尝试直接访问窗口的图形内容在macOS 10.14中不再起作用。

您可以在此上下文中创建一个unlockFocus对象并更新图形。

示例代码:

NSBitmapImageRep

答案 1 :(得分:0)

您可以尝试覆盖方法isOpaque并从那里返回YES。这将告诉OS我们自己绘制所有像素,并且不需要在视图的背面绘制视图/窗口。

- (BOOL)isOpaque {
    return YES;
}