Cocoa: NSViewController.viewWillAppear() и viewDidAppear() не вызываются, когда окно было свернуто в док

Этот вопрос касается приложения для macOS, а не для iOS.

У меня есть базовое приложение Cocoa, которое поддерживает несколько окон. Я заметил, что NSViewController.viewWillAppear() и viewDidAppear() не вызываются при запуске приложения, и ранее окно было свернуто в док-станцию.

Чтобы воспроизвести:

  • Запустите приложение и откройте новое окно
  • Свернуть окно в док (Окно → Свернуть)
  • Выйти и перезапустить приложение

→ Окно все еще должно быть свернуто в доке

  • Нажмите на окно в доке, чтобы вернуть его на экран.

Ожидал:

  • NSViewController.viewWillAppear() и viewDidAppear() должны быть вызваны

Действительный:

  • они не называются

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

Минимальный воспроизводимый пример

  1. Системные настройки → Общие → Снимите флажок Закрывать окна при выходе из приложения.
  2. Xcode → New Project → macOS App:
    • User Interface: Storyboard
    • ☑︎ Создание приложения на основе документов
  3. Откройте ViewController.swift и добавьте:

.

  override func viewWillAppear() {
      super.viewWillAppear()  [PUT BREAKPOINT HERE]
  }
  1. Open Document.swift and:
    1. Have func data(ofType typeName: String) simply return Data()
    2. Пусть func read(from data: Data, ofType typeName: String) ничего не делает (удаляет исключение)
  2. Создавайте и запускайте
  3. Cmd-S, чтобы сохранить документ, открытый по умолчанию
  4. Window → Minimize
    • Document window now minimized in the dock
  5. Cmd-Q, чтобы выйти из приложения
  6. Relaunch the app
    • Document window still sits minimized in the dock
  7. Щелкните значок окна документа в доке, чтобы вернуть его.

viewWillAppear() и viewDidAppear() вызываться не будут, так как окно не свернуто.


person Mark    schedule 20.11.2020    source источник
comment
Опубликуйте минимально воспроизводимый пример   -  person Willeke    schedule 21.11.2020
comment
@willeke Хорошо, я добавил минимальный воспроизводимый пример.   -  person Mark    schedule 22.11.2020
comment
Мне это кажется ошибкой. Обходной путь: вызовите функцию настройки из windowDidLoad или makeWindowControllers.   -  person Willeke    schedule 22.11.2020


Ответы (1)


Почему бы не использовать NSWindowDidDeminiaturizeNotification на оконном контроллере и в этом методе уведомления не отправить сообщение представлениям, нуждающимся в таком обновлении? У вас может быть флаг на оконном контроллере, чтобы отличать ваш случай от стандартного случая и отправлять это сообщение только в первом контексте. Что-то вроде этого :

 -(void) NSWindowDidDeminiaturize:(NSNotification *)notification {
     if (_justLaunched) [_myView windowDidDeminatiurizeAtLaunchTime];
     _justLaunched = NO;
}
person dspr    schedule 20.11.2020
comment
Это может быть обходной путь, но я до сих пор не понимаю, почему не вызывается viewWillAppear. Очевидно, что представление появляется в какой-то момент жизненного цикла окна... - person Mark; 20.11.2020