Thomas Redman
Thomas Redman

Reputation: 56

The view's window field is nil in viewDidAppear method?

I have several NSViewControllers that reference a field of the view's NSWindowController. My understanding of the view's lifecycle contract would indicated that I can rely on on the view's window being populated by the time the viewDidAppear is called. And that has been the case until today's apparent Xcode update (when I started Xcode it seemed to update some libraries, now at version 9.0 (9A235)). Now, when viewDidAppear is called on my NSViewController instance, the self.view.window field is actually nil! Code looks like this (with some debugging stuff added):

override func viewDidAppear() {
    super.viewDidAppear()
    if let w = self.view.window {
        if let bmw = w.windowController {
            rf = (bmw as! BudgetMunkyWindow).refreshManager;
            rf.add(listener:self);
        } else {
            print("There was not window controller");
        }
    } else {
        print("there is no window");
    }
    self.categoryTable.reloadData()
    categoryTable.expandItem(nil, expandChildren:true)
}

Did this contract change at some point in the recent past? At this point, I can't gain access to the window controller at any point during the construction of the view, which is awkward to say the least.

Upvotes: 3

Views: 1133

Answers (1)

T.J.
T.J.

Reputation: 3960

Here is a work around from my App that include some debug code. It takes 1-2 iterations to break out of the loop after the func is called from viewDidAppear

var mainWindowTrialCount: Int = 0

func setWindowTitle() {
if let window = NSApplication.shared.mainWindow {
  mainWindowTrialCount = 0
  var titleString = toggleSimulationConfigurationButton.title + ", " + selectedComputeGPUButton.title
  if selectedComputeGPUButton.title != "Compute: CPU" {
    titleString.append(", " + asyncSyncComputeButton.title)
  }
  window.title = titleString
  print(titleString)
} else if mainWindowTrialCount < 10 {
  //work around for window not being valid at viewDidAppear
  DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
    self.mainWindowTrialCount += 1
    let elaspedTime: Float = Float(self.mainWindowTrialCount) * 0.01
    print("Initialization time = \(elaspedTime)")
    self.setWindowTitle()
  }
}

}

Upvotes: 0

Related Questions