How to Reference the View's Window in Swift 3.X Using Storyboards/Cocoa

How do I open another window in macOS in Swift with Cocoa

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)

Adding a second View Controller to storyboard

You are correct that you have to create a NSViewController subclass for the second view controller. The next step to take is to set the second view controller's class to your subclass. Set the view controller's class using the identity inspector.

Sample Image

After setting the second view controller's class to your subclass, you should be able to create outlets and make connections from user interface elements in the second view controller to that view controller's source code file.

Open NSWindow from xib while using storyboards and swift

In your second nib:

class SecondNibController: NSWindowController {
override var windowNibName: String? {
return "SecondNib" // no extension .xib here
}
}

Remember to connect the window outlet of SecondNibConntroller to your window.

In your main storyboard:

class ViewController: NSViewController {
let secondNibController = SecondNibController()

@IBAction func openSecondWindow(sender : AnyObject) {
secondNibController.showWindow(nil)
}
}

OS X storyboards: using show segue without allowing duplicate new windows to show?

Edit: While the answer below does work, it is definitely not the best way. In your storyboard, select the view controller for the destination view then go to the attributes inspector and change Presentation from Multiple to Single. That's it, no code required.

view controller presentation attribute


Not sure this is the best way but in the NSViewController that is pushing the segue, you could add a property for the destination NSViewController and, in your prepareForSegue:sender: method, assign the destination view controller. Finally, in the shouldPerformSegueWithIdentifier:sender: method, check to see if the destination view controller is assigned, and, if so, bring its window to the front and return NO meaning don't perform the segue, otherwise, return YES. Here's a quick example (to be included in the NSViewController with the button to initiate the segue):

@interface ViewController ()
@property (weak) NSViewController *pushedViewController;
@end

@implementation ViewController

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
if (self.pushedViewController) {
[self.pushedViewController.view.window makeKeyAndOrderFront:self];
return NO;
}
return YES;
}

- (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender {
self.pushedViewController = segue.destinationController;
}

@end

When you close the window containing the destination view controller, this will set the pushedViewController property of the original view controller to nil so the segue will perform if the window is not already opened. Again, there may be a better way to do this. Hope this helps.

Jon

How to make two windows pop out in the beginning on a Swift 4 Cocoa application?

You have to get a reference to the window controller in your storyboard from the second window you want to show. Add this code to your NSApplicationDelegate in applicationDidFinishLaunching. Don't forget to set the identifier from the WindowController in the Storyboard

let storyboard = NSStoryboard(name: "Main", bundle: nil)
let windowController = storyboard.instantiateController(withIdentifier: "MyWindowController") as! NSWindowController
windowController.showWindow(self)


Related Topics



Leave a reply



Submit