【发布时间】:2018-08-23 14:44:51
【问题描述】:
根据 NSView 的 drawRect: 的文档
如果您的应用使用其图层对象管理内容,请使用 updateLayer 方法更新您的图层,而不是覆盖此方法。
我有一个NSView,其中包含框架提供的子视图,它们都使用drawRect: 进行绘制。这个框架提供的视图是NSView 的子视图,我需要一个层。因为我的框架提供的视图是支持层的视图的后代,所以通常不会调用drawRect:,尤其是在窗口处于活动或非活动状态的情况下(视图需要更新以反映其(非)活动状态)。
当然,如果我使包含视图不支持图层,则当窗口处于活动或非活动状态时会发生更新。
在不将框架修改为自定义分支的情况下,确保drawRect: 在我的框架提供的视图中出现的最佳途径是什么?
谢谢。
2018 年 8 月 25 日编辑:
看起来诀窍是将层次结构中的一个视图设置为,例如[view setCanDrawSubviewsIntoLayer:YES,根据文档,它使用所有子视图的drawRect: 将它们的绘图添加到它自己的层。然而,这似乎只在 10.13 中有效,并且在 10.14 测试版中被打破。我将继续寻找潜在的 API 更改,除非这是 10.14 测试版错误。
由于问题仍未解决,因此尚未真正得到解答。
【问题讨论】:
-
我想你可能会感到困惑。我不确定您到底在问什么,但父视图的
-drawRect:方法不负责调用/触发/调用其子视图的-drawRect:。每个视图(无论层与否)都会在它发生变化时被绘制出来,而 Cocoa 中的神奇显示管理器会合成生成的图像。换句话说,needsDisplay状态(最终导致新的-drawRect:消息)独立于其父视图和子视图。 -
我并不是建议
drawRect:负责子视图。我的意思是,如果我有一个通过drawRect:在层支持的视图 A 上绘制的视图 B,那么我的视图 B 当我聚焦或取消聚焦窗口时,没有调用它的drawRect:。层支持视图的后代也成为层支持,因此引用的文档表明drawRect:不会被调用。如果我没有为视图 A 添加图层,那么我的视图 BdrawRect:会在需要时调用。 -
哦,我想我现在明白了。那么为什么您的自定义
NSView不能简单地观察其窗口的NSWindowDidBecomeMainNotification和'NSWindowDidResignMainNotification` 通知并向其所有子视图发送needDisplay=YES消息?看起来很简单(而且无害)。 -
我没有自定义
NSView,除非我想分叉框架。如果我能找到一个通用的解决方案,那么我认为 PR 会受到欢迎,但主要是我试图找到行为差异的原因和解决方案。破解它以使其工作,找出区别并以正确的方式进行操作是有区别的。我不是付费专业人士,所以我更愿意了解正在发生的事情,而不是暴力破解。 -
为了清楚起见,您不必继承
NSView。 任何 对象都可以观察通知并采取一些行动(例如,您的窗口控制器)。如果您认为框架控件在层支持的视图中行为不端,那么一定要提交错误报告。但我怀疑其中涉及黑客行为......
标签: cocoa calayer nsview drawrect