OS X アプリで特定のウィンドウが表示される (ユーザーに表示される) たびに追跡したいと思います。トラッカーを呼び出すのに最も適切な場所はどこですか?
windowWillLoad、多分?
私は何かを見つけることを期待してwindowWillAppear
いましたが、iOS について考えすぎているようです。
OS X アプリで特定のウィンドウが表示される (ユーザーに表示される) たびに追跡したいと思います。トラッカーを呼び出すのに最も適切な場所はどこですか?
windowWillLoad、多分?
私は何かを見つけることを期待してwindowWillAppear
いましたが、iOS について考えすぎているようです。
などの通知を受け取るにはどうすればよいNSWindowDidBecomeMainNotification
でしょうか。メインでは、ユーザーが直接目にする画面の一番上にあるものだと思います。
参照:アップルのドキュメント
はい、ウィンドウがそのデリゲートまたはそのコントローラーにwindowWillAppear
またはwindowDidAppear
メッセージで通知するか、または のような文書化された通知を投稿することを期待するでしょうNSWindowDidAppearNotification
。しかし、残念ながら、それらのどれも存在しません。Apple にバグ レポートを提出したところ、代わりにストーリーボードとビュー コントローラーを使用するようアドバイスを受けました。これは、多数のウィンドウ コントローラーと xib を既に使用しているレガシー アプリでは役に立ちません。
サブクラス化NSWindow
およびオーバーライドorderWindow:relativeTo:
して、通知を送信できます。、 、 、 などorderBack:
、ウィンドウ自体を表示させるメッセージのほとんど (すべてではない) は、最終的にこのメソッドを通過します。ただし、は通過しないため、完全を期すためにそれをオーバーライドすることもできます。orderFront:
makeKeyAndOrderFront:
-[NSWindowController showWindow:]
orderFrontRegardless
orderWindow:relativeTo:
通知を受けるもう 1 つの方法はNSViewController
、ウィンドウに常に表示されるビューを制御する のサブクラスを作成することです。ビュー コントローラは と を受け取りviewWillAppear
ますviewDidAppear
。
サブクラス化している場合NSWindow
、またはNSViewController
他の理由ですでにサブクラス化している場合は、これらのいずれかが合理的な解決策です。
まだサブクラス化NSWindow
しておらずNSViewController
、ウィンドウに常に表示されるビューのサブクラスがない場合、別の方法として、Cocoa バインディングを使用して、ウィンドウのvisible
バインディングをオブジェクトの 1 つのプロパティに接続します。たとえば、カスタムNSWindowController
サブクラスがあります。私はそれにwindowIsVisible
プロパティを与えました:
@interface MyWindowController ()
@property (nonatomic) BOOL windowIsVisible;
@end
そして、次のようにアクセサーを実装しました。
- (BOOL)windowIsVisible { return self.window.visible; }
- (void)setWindowIsVisible:(BOOL)windowIsVisible {
NSLog(@"window %@ became %s", self.window, windowIsVisible ? "visible" : "hidden");
}
ではawakeFromNib
、次のようにウィンドウのvisible
バインディングをプロパティにバインドします。
- (void)awakeFromNib {
[super awakeFromNib];
[self.window bind:NSVisibleBinding toObject:self withKeyPath:NSStringFromSelector(@selector(windowIsVisible)) options:nil];
}
ウィンドウが表示されると、setWindowIsVisible:
setter が の引数で呼び出されますYES
。アプリ全体が非表示になっていて再表示された場合、アプリが非表示になったときに引数を指定して呼び出されなかったとしても、setter が再度呼び出されることに注意してくださいNO
。そのため、ウィンドウが以前は非表示であったと想定しないように注意してください。
また、バインディングは保持サイクルを作成する可能性があるため、ウィンドウとコントローラーを保持したくない場合を除き、ウィンドウが閉じられたときにバインドを解除する必要があります。ウィンドウがNSWindowWillCloseNotification
閉じるときに投稿するので、それを検出するための特別な魔法は必要ないことに注意してください。