David Garces
Jun 30, 2015 · 3 min read

It’s been a week since I posted a question in StackOverflow and so far no one has commented or responded at all. I decided to do a bit of Research and created a simple solution that doesn’t use the first responder. You can find and download my code on github: DavidCodesOSX -> NSToolbar with Storyboards


Checklist

This is what we’ve done so far since my last post:

  • Created an Xcode project in Cocoa for OS X using Swift 2 and Storyboards
  • Added a Toolbar (NSToolbar) to our NSWindowController
  • Added a Label to the child NSViewController.
  • Added a Textured Rounded Button (NSButton) to the NSToolbar. This button automatically became a child of my toolbar (NSToolbarItem)
  • Added the new button to the default buttons for the user.
  • Set as a final goal for my application to change the text of the label if the user clicks the button.

The application we have so far looks like this:

Main Screen
Main Screen

Solution

In Session 212: Storyboards and Controllers on OS X from WWDC14, Apple introduced the concept of containment: with storyboards you can have view controllers that have children view controllers. Most specifically, you have a window controller that has a child view controller, which can be accessed with the property contentViewController. You can find this information in the class reference for NSWindowController:

/* The view controller for the window’s contentView. Tracks the window property of the same name.
*/
@available(OSX 10.10, *)
var contentViewController: NSViewController?

This property is the link we needed in our hierarchy.

Implementation Detail

1. We need to create an outlet in our implementation of the NSViewController (ViewController.swift), so that we can access and modify our label:

@IBOutlet weak var myLabel: NSTextField!

2. Now we need a function in the same class that access the label and makes a changes it’s string value to a given value (Note that we could easily access the myLabel property directly from the containerView property in the NSWindowController, but I prefer to create this function to make things tidy, as well as easier maintenance):


func updateMyLabelText(newText: String){
myLabel.stringValue = newText
}

3. We create our custom class of NSWindowController (WindowController.swift)

4. The containerView property can manually be accessed anytime from any part of the class but we can optionally create a property that directly return the viewController in the way we want it:


var viewController: ViewController {
get {
return self.window!.contentViewController! as! ViewController
}
}

Notice that we are explicitly telling the compiler that our view controller will be returned as our custom ViewController class, you may need to change this implementation if you want to handle multiple contentViewController controllers in your application.

4. Finally we create an action that we’ll need to link to our toolbar button so that it changes the text when it is clicked. This action will read the contentViewController and send the string we want to the function we implemented in it:


@IBAction func changeText(sender: NSButton) {
viewController.updateMyLabelText(“Button clicked! The value is: \(sender.title)”)
}

And that’s it!, our button will send it’s title to the label as shown in the picture:

Label after button was clicked
Label after button was clicked

Feel free to post your views about my approach, or suggest other ways to connect my button to the view controller by leaving a comment in my post.

Remember to check out the full code for my toolbar app (NSToolbar with Storyboards) at https://github.com/gbdavid2/DavidCodesOSX.git

Happy coding.

David

David codes (swift)

My stories about programming with Swift

David Garces

Written by

Developer, Technologist and Blogger

David codes (swift)

My stories about programming with Swift

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade