2009-10-05 2 views
2

Я Cocoa новичок, так что вполне вероятно, что мой подход является неправильным, но ..Закрытия дочерних окон в Cocoa, когда главное окно закрывается

У меня есть приложение, которое открывает несколько дочерних окон (после того, как главные/родительское окно) с использованием NSWindowController и initNibWIthName:. Это прекрасно работает.

Но когда я закрываю родительское окно (используя красный x), они остаются открытыми и препятствуют закрытию приложения, пока они не будут закрыты. Это имеет смысл, поскольку я никого не закрываю.

Но как мне это сделать? Должно быть событие, которое вызывается в этот момент, но я не могу найти, что это нигде.

Уведомления, такие как applicationWillTerminate (и т. Д.), Вызываются только тогда, когда приложение фактически завершается не при нажатии кнопки закрытия.

Я думаю, что я ищу что-то похожее на сообщения типа Windows WM_CLOSE.

+0

Что делает окно «дочерним» из другого окна? ... эта парадигма совсем не применима к MacOS. true, не все окна созданы равными, но мне еще нужно увидеть два окна и воспроизвести их, создавая детей любого типа ... худший сценарий: вы управляете списком windowControllers в делетете приложения. – kent

+0

Ну, как я уже сказал, я новичок в разработке Mac, поэтому я не знаю «традиционные» термины, которые используются. Я открыл дополнительное окно (в окнах безмодельное диалоговое окно) из AppDelegate. Я пытаюсь закрыть его, когда нажата кнопка закрытия. Список оконКонтроллеры по-прежнему не учитывают важный шаг в том, что происходит при нажатии кнопки закрытия. – 2009-10-05 15:50:24

+0

Просьба представить примеры кода, демонстрирующие, как вы создаете эти дочерние окна. Стандартный эквивалент какао диалогового окна без моделирования - это лист, который является диалоговым окном. –

ответ

3
+0

WindowWillClose никогда не вызывается (для меня), но applicationwillterminate и т. Д. – 2009-10-05 13:03:16

+2

windowWill закрыть из делегата окна - applicationWillTerminate находится на делегате приложения – Mark

+0

Спасибо. У меня это работает. Просто для того, чтобы уточнить для кого-либо нового для xcode. Вы можете получить ApplicationWillTerminate и другие из AppDelegate. Чтобы использовать WindowWillClose, создайте класс WindowController (.h и .m из NSObject), создайте новый объект в своем файле nib, выберите класс WindowController и используйте ctrl grab, чтобы настроить его как делегата и voila. – 2009-10-05 16:54:05

2

для Windows и приложений не то же самое, что в Mac OS X.

Если у вас есть интерфейс одного окна, с главного окна и никаких других за исключением О , Предпочтения и т. Д., Тогда вы должны реализовать applicationShouldTerminateAfterLastWindowClosed: в делетете приложения и вернуть YES. Это единственный способ (кроме того, что вы делаете это вручную), что закрытие окна заставляет приложение выйти.

Если у вас есть интерфейс с несколькими окнами (как в типичном приложении на основе документов), вы должны сделать все эти одноранговые окна друг с другом. Окна, такие как инспекторы и палитры инструментов, должны быть плавающими панелями, а не обычными окнами. И закрытие последнего окна никогда не должно прекращаться после такого приложения.

4

Ближайший эквивалент, который вы найдете, это NSWindowWillCloseNotification, размещаемый окном перед его закрытием. Вы, вероятно, можете получить дочерние окна, чтобы закрыть себя, когда родительское окно закрывается с помощью:

NSWindow *parentWindow; 
NSArray *childWindows; 

NSNotificationCenter *noteCenter = [NSNotificationCenter defaultCenter]; 
for (NSWindow *childWindow in childWindows) { 
    [noteCenter 
    addObserver:childWindow selector:@selector(close) 
    name:NSWindowWillCloseNotification object:parentWindow]; 
} 

Если окно ребенка будет освобождаться до его родителей, не забудьте отменить его для уведомлений, прежде чем это произойдет.

Метод делегата, упомянутый Марк, - это удобный метод для делегата, который избавляет их от необходимости регистрироваться для уведомления, которое они, вероятно, захотят в любом случае. Вам не нужно создавать оконный контроллер только для получения этого сообщения; просто отправка окна [window setDelegate:myObject] вызовет myObject, чтобы получить сообщение -windowWillClose:, если оно отвечает на метод.

Кстати, то, что Какао вызывает «детские окна», отличается от того, о чем вы думаете. Они не адресованы в Window Programming Guide, но если вы посмотрите на документацию по связанным методам на NSWindow, вы увидите, что они в основном отслеживают перемещения их родительского окна, так что они перемещаются вместе с ним.

Если вы идете в Cocoa из программирования Win32, вы можете обнаружить, что Apple Porting to Mac OS X from Windows Win32 API помогает выделить концептуальные различия между Win32 и Cocoa.

+0

Спасибо за ваш ответ (ы). Теперь я понял, что полностью не понял, как окна Cocoa свисают вместе, что означает, что мой оригинальный вопрос не увенчался успехом. Я начал с нуля делать что-то более ориентированным на mac. Для любых оконных программистов, читающих это, вы можете получить класс, созданный в Interface Builder, используя выход, такой как IBOutlet NSWindow * myWindow; Это, по-видимому, считается настолько очевидным (как в мире круглое), что его не нужно прописывать (что он сделал для меня !!) – 2009-10-07 16:55:46

+0

он должен читать 'selector: @selector (close)' вместо 'selector: @ (close)' – MKroehnert

+0

В какао действительно есть дочерние окна, даже если они сильно отличаются от того, как Windows использует этот термин. И вам, похоже, нужно знать, когда ваш родитель закрывается (в противном случае есть некоторые ошибки, которые могут возникать с пробелами). Поэтому да, я рекомендую наблюдать NSWindowWillCloseNotification (это должно быть отправлено автоматически, нет необходимости отправлять его в цикле). –

Смежные вопросы