问题
I am working on a macOS app that presents a list of customer master records in a table view. Double-clicking a row in the table view should open a new window where the user can view and edit the customer information.
This is an Xcode 8.3.3 project using a storyboard and Swift.
It is not a document or core data app.
I have the main window working up to the point where the table view is displaying the records correctly and the associated view controller is receiving the double-click events and logging them to the console.
I have created an additional window controller and view for the edit window and verified its basic functionality by temporarily marking it as the initial controller.
What I haven't been able to figure out is how to display a new instance of that window when the user double-clicks a row.
Thanks to @Joshua Nozzi I'm closer. Here is the code at this point.
let storyboard = NSStoryboard(name: "Main", bundle: nil)
if let windowController = storyboard.instantiateController(withIdentifier: "xyzzy") as? NSWindowController
{
windowController.showWindow(self)
}
It's generating a
(Storyboard: 0x620000000680) doesn't contain a controller with identifier 'xyzzy'
error.
回答1:
The Window Programming Guide is a great place to understand how windows are managed in general.
Specifically (assuming you know how to present a window controller scene in storyboards), you need somewhere to store references to the new window controllers so they’re not immediately deallocated (and disappear) when presented.
In your case, you may want to keep an array of your open detail windows in the master window controller, so that if the master goes away, the details do as well. When a detail window is open (a controller instance is created and its window shown), you’ll store its controller in the array; when closed, you remove its controller from the array so it’s deallocated.
There are a number of ways to do this, depending on how much control you want, how you want child window ownership to work, etc., but this basic pattern is usually sufficient.
To instantiate a new window controller scene from a storyboard:
var myWindowController = NSStoryboard(name: "MyStoryboardFileName", bundle: nil)?.instantiateControllerWithIdentifier("MyWindowControllerIdentifier") as MyWindowControllerClass
myWindowController?.showWindow(self)
回答2:
Confirmed. This is such a major gotcha in the UI. And it is buggy to boot: Storyboard doesn't contain a controller with identifier 'MainWindow' A whole day wasted troubleshooting this issue.
来源:https://stackoverflow.com/questions/45119813/how-do-i-open-another-window-in-macos-in-swift-with-cocoa