10
votes

I try to show a NSViewController via a storyboard segue (OSX). The opening window will be an inspector window, so it should be non-modal.

When I create an action segue by Ctrl-dragging from the trigger button to the window controller I am offered the following segue style options:

  • Modal
  • Sheet
  • Popover
  • Custom

The first three options are obviously not appropriate.

I'm sure I could create a custom segue to show the view. This would involve creating a class, implementing some methods and so on.

However, since my requirement seems quite basic to me, I wonder if I'm missing something obvious, a simple way to open a non-modal window via canvas.

I'm using XCode6-Beta3.

1
Does sour view (controller) have a navigation bar?Drux
The main window has a navigation bar (the trigger button actually is inside a toolbar). The view controller I'm trying to open does not.mic
Hmm .. in that case if you ctrl-drag from the 1st to the 2nd view in IB (and say Xcode 5.1.1), don't you get the option "Push" as well? (I assume that's your "standard segue".)Drux
Unfortunately not. I guess 'Push' might be only an option for IOS storyboards, not OSX. The standard segue in my case is modal.mic
Sorry, I was on the wrong (iOS) track ...Drux

1 Answers

13
votes

At least right now (Beta3), a non-modal view needs to have its own window, and there's no simple way to create a segue for that.

Instead, drag a new Window Controller object onto your Storyboard. It will come with its own content view as a Relationship Segue. However, if there's a different view you want to use for the window (e.g.: a Tab View Controller), simply delete the new View Controller and control-drag from the new Window Controller to the View Controller whose view you wish to use for the window content.

Important: Select the Window Controller object in the Storyboard, and in the Identity Inspector, set the Storyboard ID to a string that will identify the window (e.g.: "Inspector").

Then, just write a little code to show the window:

var inspectorController: NSWindowController?
@IBAction func showInspector(sender : AnyObject) {
    if !inspectorController {
        let storyboard = NSStoryboard(name: "Main", bundle: nil)
        inspectorController = storyboard.instantiateControllerWithIdentifier
           ("Inspector") as? NSWindowController
    }
    if inspectorController { inspectorController!.showWindow(sender) }
}

I actually found it preferable not to use the Main storyboard for any windows at all. One of the reasons is because with Storyboards (at least right now), there's no way of intercepting the initial segue when the application launches, and windowWillLoad is never called on the main Window Controller.

Instead, create separate storyboards for the Application and/or Document windows, and use an AppDelegate class to instantiate them. More information and a working example in this thread.