macOS Development for Beginners: Part 2

Learn how an app starts, how the UI is constructed, and all the way to handling user interaction in this macOS development tutorial for beginners! By Roberto Machorro.

Leave a rating/review
Save for later
Share
Update note: Roberto Machorro updated this tutorial for Xcode 12 and Swift 5. Sarah Reichelt wrote the original article.

In Part 1 of this series, you learned how to install Xcode, how to create a new app, add UI, connect the UI to the code, run the app, debug the app and how to get help. If you are unsure of any of this, go back and run through Part 1 again.

In this part, you are going to create the user interface for a more complex app. You will learn how to allow for resizable windows, as well as designing and navigating to a second window to display your app’s preferences.

Getting Started

Open Xcode and click Create a new Xcode project from the Welcome window or select File/New/Project… Just as you did in Part 1, select macOS/Application/App. Click Next, give your app a name of EggTimer, make sure the interface is Storyboards and that language is Swift, everything else should be unchecked. Click Next and choose where to save your project.

Build and run your new app just to make sure that everything is working correctly.

EggTimer App

The app that you are about to build is EggTimer; it counts down from the selected time showing the time remaining. There is a graphic that changes as your egg boils and a sound that plays when your egg is ready. A second window will show the app’s preferences.

Open Main.storyboard from the Project Navigator. As you saw in part 1 of this series, you already have three components:

  • Application Scene
  • Window Controller Scene
  • View Controller Scene

Application Scene contains the menu bar and menus that appear whenever the app is running. Window Controller is the part of the app that defines how the window will behave: how it will resize, how new windows will appear, whether the app will save the window size and location and so forth. A window controller can manage more than one window, but if they need different properties, you will need to add another window controller.

View Controller displays the user interface inside the window — that is where you will layout the UI for the main display.

Notice that the Window Controller has an arrow pointing into it. This indicates it will control the initial display when the app starts up. You can check this by selecting the Window Controller in the Document Outline and going to the Attributes Inspector. Uncheck Is Initial Controller and the arrow will disappear. Check it again as you do want this to be the initial controller.

Window Controller

Before you start on the user interface, make sure you have selected Main.storyboard in the Project Navigator. Click inside the Window Controller to select its window. The Window Controller in the Visual Editor shows the text “View Controller” because this is what it contains. For this app, you do not want to allow the window to shrink below 346 x 471 pixels. This will also be the starting size of the window.

Go to the Size Inspector in Utilities and set the Content Size Width to 346 and the Content Size Height to 471. Check the Minimum Content Size checkbox and make sure the width and height values are the same as for the content size. The Window Controller in the Visual Editor will have resized. You may want to move it now so that it is not overlapping other objects.

While not strictly necessary, it is easier to visualize if you adjust the View Controller to the same dimensions as its containing Window Controller. Click the View Controller making sure that its View is selected in the Document Outline. In the Size Inspector set the width and height to 346 and 471 respectively. Re-position as needed to see all the objects. Now the WindowController and the ViewController are shown at the same size in the Visual Editor.

Select the window in the WindowController and change its title to Egg Timer in the Attributes Inspector. Set the Autosave name to EggTimerMainWindow so that the size and positioning of the window will be saved automatically between launches.

If you are an iOS programmer, you will have dealt with various screen sizes for different device types and rotations. In macOS programming, you have to deal with an infinite variety of window sizes and aspect ratios, which is why I made the initial dimensions for this window a bit weird. Luckily, Auto Layout handles all this for you.

Laying out the UI – part 1

The basic UI consists of 2 stack views. The first one contains the time remaining text and the egg image. The second one contains the 3 buttons along the bottom. Start with the buttons:

  • Search for “Button” in the Object Library.
  • Drag a Gradient button into the View Controller.
  • Using the Attributes Inspector, delete its image and set its title to Start.
  • Change the font to System 24.
  • Expand the button to show all the text.
  • With the Start button selected, press Command-D twice to create 2 more copies.
  • Drag the new buttons out so you can see them all.
  • Edit the titles of the new buttons to Stop and Reset.
  • Select all 3 buttons and choose Editor/Embed In/Stack View.

To make the buttons fill the stack view, select the new Stack View and make the following changes in the Attributes Inspector:

  • Distribution: Fill Equally
  • Spacing: 0

Click the Add New Constraints button at the bottom of the Visual Editor and set the left, right, bottom and height constraints as shown. Select Update Frames: Items of New Constraints and then click Apply 4 Constraints.


The stack view is now positioned correctly, but the buttons are shorter than the stack view. In the Document Outline, Control-Drag from the Start button to the Stack View and select Equal Heights. Do the same for the other two buttons.

The button stack view is now exactly as you wanted it.

Build and run the app. Try resizing the window: the buttons stick to the bottom of the window and resize to fill the width evenly.

As a final touch, disable the Stop and Reset buttons by unchecking Enabled in the Attributes Inspector. It makes no sense to have them enabled before the timer has started.

Contributors

Zoltán Matók

Tech Editor

Chris Belanger

Editor

Michael Briscoe

Final Pass Editor and Team Lead

Over 300 content creators. Join our team.