Reputation: 470
I'm working on updating a MacOS program in Swift 4/Xcode 12. I have a custom view controller "HelloWorldViewController" which previously I was displaying in a window by itself. HelloWorldViewController uses the storyboard HelloWorldViewController.storyboard rather than Main.Storyboard. Here's the code for toggling the Window containing the view which works just fine.
func toggleHelloWorldWindow() {
if helloWorldViewCtrl == nil {
let myStoryboard = NSStoryboard(name: NSStoryboard.Name("HelloWorldView"), bundle: nil)
helloWorldWindowCtrl = myStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("HelloWorldWindow")) as? NSWindowController
guard helloWorldWindowCtrl != nil else {return}
helloWorldViewCtrl = helloWorldWindowCtrl!.window!.contentViewController as? HelloWorldViewController
}
if let myWindowController = helloWorldWindowCtrl {
if myWindowController.window!.isVisible {
myWindowController.window!.orderOut(self)
} else {
myWindowController.showWindow(helloWorldWindowCtrl)
}
}
}
However I've decided that the best way to use the controller is to embed it in the main application rather than a separate window. It seemed that the way to do this was to use a NSContainerView which I was able to get working just fine if I had the storyboard for the custom view in the same storyboard file as the main app.
But for the life of me I've been unable to get it to point to an external storyboard. It always crashes in viewDidLoad of the custom view controller when I set values for items on the custom view page as they are all nil (ie, the view didn't render?)
class HelloWorldViewController: NSViewController {
@IBOutlet weak var helloWorld: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
helloWorld.stringValue = "Hello world..." (crashes)
}
}
After two days of fussing with it was able to make it work programmatically (which is just fine for my purposes and likely the solution I'll stick with) but I'm still wondering what was I missing in the process of trying to do it with exclusively storyboards? I tried to set up a segue but could not find any way to tell it the storyboard filename and just using the scene identifier resulted in the same crash.
(programatic version in main app's viewDidLoad() which works fine)
let myStoryboard = NSStoryboard(name: NSStoryboard.Name("HelloWorldView"), bundle: nil)
if let helloWorldWindowCtrl = myStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("HelloWorldWindow")) as? NSWindowController,
let controller = helloWorldWindowCtrl.window!.contentViewController as? HelloWorldViewController
{
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
helloWorldView.addSubview(controller.view)
NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: helloWorldView.leadingAnchor, constant: 0),
controller.view.trailingAnchor.constraint(equalTo: helloWorldView.trailingAnchor, constant: 0),
controller.view.topAnchor.constraint(equalTo: helloWorldView.topAnchor, constant: 0),
controller.view.bottomAnchor.constraint(equalTo: helloWorldView.bottomAnchor, constant: 0)
])
}
Upvotes: 0
Views: 112