Да, можно было бы ожидать, что окно уведомит своего делегата или свой контроллер с помощью сообщения windowWillAppear
или windowDidAppear
или опубликует документированное уведомление, например NSWindowDidAppearNotification
. Но увы, таких нет. Я подал отчет об ошибке в Apple, и мне посоветовали вместо этого использовать раскадровку и контроллер представления. Это бесполезно в устаревших приложениях, которые уже используют кучу оконных контроллеров и xib.
Вы можете создать подкласс NSWindow
и переопределить orderWindow:relativeTo:
для отправки уведомления. Большинство, но не все сообщения, из которых открывается окно, в конечном итоге проходят через этот метод, включая orderBack:
, orderFront:
, makeKeyAndOrderFront:
и -[NSWindowController showWindow:]
. Но orderFrontRegardless
не проходит через orderWindow:relativeTo:
, поэтому для полноты вы также можете переопределить это.
Еще один способ получать уведомления — создать подкласс NSViewController
, управляющий некоторым представлением, которое всегда отображается в окне. Контроллер представления получит viewWillAppear
и viewDidAppear
.
Если вы уже создаете подклассы NSWindow
или NSViewController
по какой-то другой причине, любое из этих решений является разумным решением.
Если вы еще не создаете подкласс NSWindow
и у вас нет подкласса NSViewController
для представления, которое всегда отображается в окне, то другим способом является использование привязок Cocoa для подключения привязки окна visible
к свойству одного из ваших объектов. Например, у меня есть собственный подкласс 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:
с аргументом YES
. Обратите внимание, что если все приложение скрыто и появляется снова, метод установки вызывается снова, даже если он не был вызван с аргументом NO
, когда приложение было скрыто. Поэтому будьте осторожны, чтобы не предположить, что окно ранее было скрыто.
Кроме того, привязка может создать цикл сохранения, поэтому вам, вероятно, следует отвязать ее, когда окно закрыто, если только вы не хотите сохранить окно и контроллер. Обратите внимание, что окно действительно публикует NSWindowWillCloseNotification
, когда оно закрывается, поэтому вам не нужна какая-то особая магия, чтобы обнаружить это.
person
rob mayoff
schedule
31.07.2017