macOS Controls Tutorial: Part 2/2

Learn how to use common macOS UI controls like NSSlider, NSImageView and more in the final part of this series — updated for Xcode 8.2 and Swift 3! By Ernesto García.

Leave a rating/review
Save for later
Share

Update Note: Updated for Xcode 8.2 / Swift 3 by Ernesto García. Previous update to Xcode 6.3 / Swift 1.2 by Michael Briscoe. Original post by Ernesto García.

Welcome back to the second and final part of this macOS Controls tutorial series!

In the first part of this tutorial, you started building a Mad Libs style macOS application, where the user enters various words and phrases to create a funny sentence.

Along the way, you learned about some of the core UI macOS controls — namely, Text Fields, Combo Boxes, Pop Up Buttons, Push Buttons and Text Views.

More macOS Controls

In this final part of the tutorial, you’ll finish off your application, and learn how to use the following:

  • Sliders
  • Date Pickers
  • Radio Buttons
  • Check Boxes
  • Image Views

At the end of this two-part tutorial you’ll have a solid understanding of macOS controls.

This tutorial will pick up where you left off. If you don’t have it already, here’s the final project of the first part.

It’s time to get to work!

Slipping and Sliding — NSSlider

A slider is a control that lets the user choose from a range of values. A slider has a minimum and a maximum value, and by moving the control’s knob, the user can choose a value between those two limits. Sliders can be either linear or radial. What’s the difference between the two, you ask?

Linear sliders can be either vertical or horizontal, and they let you choose a value by moving the knob along the track. A really great example of linear sliders is in macOS’ Mouse preferences panel:

slider-mouse

Radial sliders are a little different — they are displayed as a small circle with a knob, which can be rotated a full 360 degrees. To select a value, you click and drag the knob to the required position. You can find a great example of radial sliders in Adobe Photoshop, where they’re used to define the angle of a gradient, as such:

The control responsible for this on macOS is an NSSlider.

All three types of sliders (horizontal, vertical and radial) are in fact the same control, NSSlider. The only difference is how they’re displayed. Interface Builder has an object in the Object Library for each of the three types, as shown below:

sliders-ib

Slider Semantics

There are two common tasks you’re likely to perform when working with sliders: getting or setting the current value, and getting and setting the high and low limits of the slider’s range. These properties are outlined here:

// getting & setting an integer value
let theInteger = mySlider.integerValue
mySlider.integerValue = theInteger

// getting & setting a float value
let theFloat = mySlider.floatValue
mySlider.floatValue = theFloat

// getting & setting a double value
let theDouble = mySlider.doubleValue
mySlider.doubleValue = theDouble

// getting & setting the minimum value of the range
let theMinimumValue = mySlider.minValue
mySlider.minValue = theMinimumValue

// getting & setting the maximum value of the range
let theMaximumValue = mySlider.maxValue
mySlider.maxValue = theMaximumValue

Again, nothing too surprising here — if you’ve learned anything by now, it’s that implementing standard UI macOS controls is a fairly straightforward exercise. Move on to the next section to include an NSSlider in your app!

Pick a Number, Any Number

Open Main.storyboard. Locate the Label control In the Object Library palette and drag it onto the content view below the Phrase label. Resize the window vertically and move the Go! button down if you need to make space for it.

Double-click the control to edit its default text, and change it to Amount: [10]. Find the Horizontal Slider control and drag it onto the window, placing it to the right of the label.

Click on the slider to select it. Open the Attributes Inspector and set the Minimum value to 2, and the Maximum value to 10. Change the Current value to 5. This will be the default value of the slider when the user first runs the app.

Make sure that Continuous is checked. This tells the slider to notify any change in the slider’s value.

slider-add

Now you need to create two outlets; one for the slider, and one for the label. Wait, you may say — that’s a little different. Why are you adding a property for the label?

That’s so you can update the label’s text to list the current amount whenever the value of the slider is changed; hence why you set the Continuous property on the slider. Aha! Makes sense now, doesn’t it?

Open the Assistant editor and make sure ViewController.swift is open. Ctrl-Drag from label to ViewController.swift to create a new outlet.

slider-drag

In the popup screen, name the outlet amountLabel.

amountlabel-drag2

Repeat the above process with the slider, naming the outlet amountSlider.

Now you need to add an action that will be called when the slider value changes. You already created an action for your button in Part 1; adding an action is very much like creating an outlet, so you’ll get a little more practice!

Select the slider and Ctrl-Drag to ViewController.swift anywhere within the class definition:

slider-action-drag

In the popup window, be sure to set the connection as an action rather than a outlet. Name it sliderChanged, like so:

slider-action2

Now you need to update the label whenever the action is called.

Open ViewController.swift and add the following code inside sliderChanged():

let amount = amountSlider.integerValue
amountLabel.stringValue = "Amount: [\(amount)]"

A quick review of the code above shows that you first read the slider’s current value. Then you set the value of the label to a string containing the slider’s value. Please note, that although amountLabel cannot be edited by the user from the UI, it is still editable programmatically.

Note: This example uses integerValue to get a nice round number, but if you need more precision you could use either floatValue or doubleValue for your slider.

Build and run the app. Try moving the slider back and forth to see the label update with the slider’s current value:

buildrun-slider

There’s one small problem. Did you notice it? The label doesn’t display the correct value when the app first launches! While it’s not a big problem, it makes the app look unfinished. It’s because the label is only updating when the slider’s knob is moved.

Fear not — it’s very easy to fix.

Add the following code to the end of viewDidLoad():

// Update the amount slider
sliderChanged(self)

Now the app will call sliderChanged() at launch, and that will update the label. Neat!

Build and run. The label now displays the correct value at first run, which is a small touch, but is one of those “fit and finish” elements that make your app look polished.

What about more complicated values, such as calendar dates? Yup, macOS has those handled too! :]

Ernesto García

Contributors

Ernesto García

Author

Gabriel Miro

Tech Editor

Chris Belanger

Editor

Michael Briscoe

Final Pass Editor and Team Lead

Over 300 content creators. Join our team.