Instantiating Views from Mac Storyboards

May 30th, 2017

Filed under: Cocoa, Mac Development | Be the first to comment!

This is another post I’m writing as a reference to myself in case I need to deal with this subject in the future. There may be better ways to instantiate views than what I describe here. I’m sharing this information because there’s not much information available on Mac storyboards.

Reading the following articles may help you follow along:

Introduction

When developing user interfaces for Mac apps, you can normally lay out the whole interface in Interface Builder at design time. But sometime you need to add user interface elements at run time. Many PDF viewers let people add sticky notes to PDF documents. The developer of a PDF viewer would create a text view or custom view for the sticky note in Interface Builder but wait until the user decides to add a sticky note to add the view to the PDF document.

Instantiating a view from a storyboard involves the following high level steps:

  1. Create a subclass of NSViewController for your view.
  2. Add a new scene to the storyboard for your view controller.
  3. Set the class of the new scene’s view controller to your subclass.
  4. Add an IBAction to the view controller that will create the view.

Creating a View Controller Subclass

Storyboard scenes need a view controller. If you’re going to instantiate a view from a storyboard, you need to create a view controller for the view.

To add a view controller to your project, choose File > New > File in Xcode. Select Cocoa Class from the list of file templates. Name your class and make it a subclass of NSViewController. When you’re done, the class should look similar to the following:

class StickyNoteViewController: NSViewController {
    @IBOutlet var textView: NSTextView?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
    }

}

I decided to stick with the sticky note theme and use a text view as the sticky note. Your class won’t have the @IBOutlet variable. Add an outlet for your view so you can connect it in Interface Builder.

Add a New Scene

Open your storyboard. Drag a view controller from the object library to the storyboard canvas to create a new scene.

Add your view to the view controller in the new scene. Configure the view using the attributes inspector. If you created an outlet for the view in your view controller subclass, connect the view to that outlet.

Set the View Controller Class

Now that you’ve added the scene, set the view controller class to your subclass. Select the view controller in Interface Builder and open the identity inspector.

CustomClassAndStoryboardID

Enter the name of your view controller subclass in the Class combo box.

While you are in the identity inspector, enter a name for the view controller in the Storyboard ID text field. You will need this ID when you load the view controller from the storyboard.

Add an IBAction to Create the View

Now it’s time to instantiate the view. Create an IBAction in the view controller where you’re going to create your view. In the IBAction you’ll instantiate the view.

@IBAction func addStickyNote(_ sender: AnyObject) {
    if let board = storyboard {
        let stickyNoteController = board.instantiateController(withIdentifier: "stickyNote")
            as! StickyNoteViewController
        addChildViewController(stickyNoteController)
        view.addSubview(stickyNoteController.view)
    }
}

What the code does is load the NSViewController subclass from the storyboard, add the view controller as a child view controller, and add the view as a subview.

Don’t forget to add a menu item or a control and connect it to this IBAction.

Facebooktwittergoogle_plusredditmail

Tags:


Leave a Reply

Your email address will not be published. Required fields are marked *