I'm trying to make a macOS app without using Interface Builder. My project builds and runs, but my primary view controller doesn't seem to be loading its view. That is, the viewDidLoad()
method is not invoked. I'm using Xcode-beta 8.0 beta 6 (8S201h).
The Swift 3 documentation for NSViewController
says this about the view
property:
If this property’s value is not already set when you access it, the view controller invokes the
loadView()
method. That method, in turn, sets the view from the nib file identified by the view controller’snibName
andnibBundle
properties.If you want to set a view controller’s view directly, set this property’s value immediately after creating the view controller.
And for viewDidLoad
:
For a view controller created programmatically, this method is called immediately after the
loadView()
method completes.
Finally, for isViewLoaded
:
A view controller employs lazy loading of its view: Immediately after a view controller is loaded into memory, the value of its
isViewLoaded
property isfalse
. The value changes totrue
after theloadView()
method returns and just before the system calls theviewDidLoad()
method.
So the documentation leads me to believe it is possible.
My project looks like this:
.
├── main.swift
└── Classes
├── AppDelegate.swift
└── Controllers
└── PrimaryController.swift
main.swift
import Cocoa
let delegate = AppDelegate()
NSApplication.shared().delegate = delegate
NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
AppDelegate.swift
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
let pc = PrimaryController(nibName: nil, bundle: nil)!
print(pc.isViewLoaded)
pc.view = NSView()
print(pc.isViewLoaded)
}
}
PrimaryController.swift
import Cocoa
class PrimaryController: NSViewController {
override func loadView() {
print("PrimaryController.loadView")
}
override func viewDidLoad() {
super.viewDidLoad()
print("PrimaryController.viewDidLoad")
}
}
Building and running a project with the above yields this console output:
false
true
That is, the view loads for the controller, but the loadView
and viewDidLoad
methods are never invoked.
What am I missing?