0
votes

This question is about a macOS app, not iOS.

I have a basic Cocoa app that supports multiple windows. I noticed that NSViewController.viewWillAppear() and viewDidAppear() are not called when the app launches and the window was minimized to the dock previously.

To reproduce:

  • Launch the app and open a new window
  • Minimize the window to the dock (Window → Minimize)
  • Quit and relaunch the app

→ The window should still be minimized in the dock

  • Click on the window in the dock to bring it back on screen

Expected:

  • NSViewController.viewWillAppear() and viewDidAppear() should be called

Actual:

  • they are not called

This is a problem, because I need a reference to the NSWindow in my view controller to finish some setup so I can't simply hook into viewDidLoad().

Minimal, reproducible example

  1. System Preferences → General → Uncheck "Close windows when quitting an app"
  2. Xcode → New Project → macOS App:
    • User Interface: Storyboard
    • ☑︎ Create Document-Based Application
  3. Open ViewController.swift and add:

.

  override func viewWillAppear() {
      super.viewWillAppear()  [PUT BREAKPOINT HERE]
  }
  1. Open Document.swift and:
    1. Have func data(ofType typeName: String) simply return Data()
    2. Have func read(from data: Data, ofType typeName: String) do nothing (remove the exception)
  2. Build & run
  3. Cmd-S to save the document that opened by default
  4. Window → Minimize
    • Document window now minimized in the dock
  5. Cmd-Q to quit the app
  6. Relaunch the app
    • Document window still sits minimized in the dock
  7. Click on the document window icon in the dock to bring it back

viewWillAppear() and viewDidAppear() will not be called as the window is unminimized.

1
@willeke Ok, I added a minimal, reproducible example. - Mark
It looks like a bug to me. Workaround: call a setup function from windowDidLoad or makeWindowControllers. - Willeke

1 Answers

0
votes

Why not using NSWindowDidDeminiaturizeNotification on the window controller and, in that notification method, send a message to the view(s) needing this kind of update ? You could have a flag on the window controller to differentiate your case from a standard case and only send that message in the first context. Something like this :

 -(void) NSWindowDidDeminiaturize:(NSNotification *)notification {
     if (_justLaunched) [_myView windowDidDeminatiurizeAtLaunchTime];
     _justLaunched = NO;
}