NSViewController
中有一个方法叫做viewDidAppear
。文档说:
在完成视图初始外观中涉及的任何绘图和动画后调用此方法。
如果没有
NSViewController
类,并且您手动管理 NSView
对象树,您如何实现类似的东西?我没有找到订阅“出现”事件或有关 NSView
的通知的方法。
我看不到订阅“出现”事件或通知的方法 关于 NSView。
没有一个,因为如果您的视图不是由
NSViewController
管理,那么它就不会参与 NSViewController
生命周期。
如果您想手动跟踪视图“出现”的时间,那么您需要确定“出现”在您的用例上下文中的含义。
对于初始外观,您需要查看:
NSView.viewDidMoveToWindow
NSView.viewDidMoveToSuperview
对于短暂的外观,您需要查看:
NSView.viewDidHide
NSView.viewDidUnhide
您可能还想查询适当的属性:
NSView.hidden
NSView.hiddenOrHasHiddenAncestor
如果您关心父窗口的“外观”,那么请考虑:
NSWindow...Notification
通知,因为其中很多与窗口的可见性或“隐藏性”相关。如果您在工作表或其他类型的模态容器中显示视图,那么我建议首先使用
NSViewController
实现它,然后在 viewDidAppear
上设置断点。回溯将显示之前调用了哪些方法,您可以根据您的用例在调用堆栈中选择一个足够高的方法。
我在一些应用程序中广泛使用了
NSViews
,但没有视图控制器。在大多数情况下,我只是在初始化程序中设置视图,因为我很少会创建视图但不会立即呈现。
如果视图正在执行诸如接收通知、运行动画或连续重绘之类的操作,并且您希望根据视图的可见性启动或停止这些操作,则只需重写上面相应的
NSView
方法即可。
但是,我发现,如果我看到自己使用该模式,那么该视图很可能会做超出其应做的事情,并且我将该代码提取到其他一些类中,我可以独立于该类显式启动和停止视图的可见性。 YMMV...
您可以重写
init
方法并在那里运行您自己的代码
类似:
- (instancetype)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if( !self ) return self;
[self myCustomInit];
return self;
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if( !self ) return self;
[self myCustomInit];
return self;
}