Make App Pie

Training for Developers and Artists

Swift WatchKit: Introducing Navigation to the Apple Watch(Part 2: Hierarchical Interfaces)

2015-05-22_06-00-02

Apple WatchKit  gives you a choice when  it comes to navigation. You can be Page-based as we introduced in our last lesson. Another alternative, is hierarchical interfaces, which closely resemble navigation controllers on the phone.  In this lesson, we’ll introduce the hierarchical type of navigation by setting up a small app.

Hierarchy Controllers

Pages are linear while hierarchical interfaces are tree like. They can branch depending on interaction with the user. They also more easily share data through a  value called a context.

Make a new single-view project in Xcode using Swift called SwiftNavigationDemo. Once it loads,  Select an Apple Watch  WatchKit App for this application.

2015-05-20_05-26-51

We will not use notifications. In the next window, make sure both glances and notifications are checked off.

2015-05-20_05-27-39

Click Finish and then Activate. In the navigator, find the WatchKit App group. Open the Interface.storyboard.

2015-05-21_05-36-20

You will have an empty storyboard with one controller. In the object inspector, find the Interface controller, which should be at the top of the list.

2015-05-20_05-31-14

Drag three interface controllers to the storyboard, placing them next to each other like this:

 2015-05-21_05-39-59

Select the main interface. In the Attribute inspector, set the title and Identifier to Main

2015-05-21_05-44-35

Do the same for the other two controllers, naming the upper one Up Branch and the lower one Down Branch.  Your storyboard should look like this :

2015-05-21_05-46-45

On the main controller, add two buttons.  Title one button Up and the other button Down. Position the Up button Horizontal center and Vertical top. Position the Down button as Horizontal Center and Vertical Bottom.

2015-05-21_05-53-01

Control-drag from the Up button to the Up Branch interface until the interface highlights.

2015-05-21_05-59-19

Release the mouse button. You get a menu of segues.  Select push.

2015-05-21_06-00-06

You get a segue from the button to the interface.

2015-05-21_06-04-03

Notice that the segue menu was context sensitive. When you control drag from a button, you get the two action segues of push and modal. When you control dragged from interface to interface in the last lesson, you got a page segue.

The up branch interface now has a back arrow to return us to the previous controller.

Control drag from the Down button to the Down branch interface, and select push. Your storyboard should look like this:

2015-05-21_06-09-24

Build and run.  We get the two buttons.

2015-05-21_06-11-29

press the Up button.

2015-05-21_06-21-45

Tap  the  < to go back to the main interface.  Press the Down button. Our app works.

2015-05-21_06-23-24

Notice that our titles get compressed when the time appears on the watch. It is a good idea to keep titles very short.

If you only are interested in navigation, segues are good enough.  As an exercise, add two more interfaces by  segues to the bottom controller.

2015-05-21_06-31-26

Programmatic Hierarchical Interfaces

You can begin to see that you can get complex user interfaces using a hierarchy. You can use a programmatic approach to hierarchical interfaces for even more power.

We will need a new view controller on the extension to do this.  When adding view controllers for the watch,  it is vital the controller be on the extension, not the phone bundle or the watch app.  Press Command-N to get a new file. Select a new Cocoa Touch class. Make a file named UpInterfaceController subclassing  WKInterfaceController

2015-05-21_06-37-40

In the next step be careful. When you save the file,  Xcode may assume this is a file for the WatchKit app. You might see it wants to save to the WatchKit App.

2015-05-21_06-40-04

It also wants to assign it to the wrong group and target.

2015-05-21_06-40-23

Select the group drop down menu and change the group to the extension’s group

2015-05-21_06-41-23

The file’s location and targets will change to show this. Click Finish.  The file stores in the correct place.

2015-05-21_06-46-40

Go to the watch storyboard. Select the Up Branch interface.  go to the identity inspector and change the class to UpInterfaceController.

2015-05-21_06-47-36

Add a button to the top, a switch in the center and a switch on the bottom . Title the button Go!,  the middle switch Gray and the bottom switch Dark like this:

2015-05-21_07-04-26

Add two more interfaces to the storyboard.  In the attributes inspector set the Identifier and Title to Gray. On the Dark switch, set the identifier and title to Color. On the Gray, set the background color to Dark Gray. On the color, set the background for a dark blue or red-blue color of your choice . I used hex #440088 in the color chooser.

2015-05-21_07-13-41

Once done, your storyboard should look like this:

2015-05-22_05-39-29

Add two more controllers. Press Command-N and add another WKInterfaceController named GrayInterfaceController, once again making sure you change the group to the Extension. Once done, add one more WKInterfaceController to the extension named ColorInterfaceController.  In the identity inspector make the class of the Gray Interface  GrayInterfaceController and the color interface ColorInterfacecontroller.

Open the assistant editor and select the Up Branch interface.

Control-drag from the gray switch  to the code and make an outlet named navigationSwitch. Control-drag from the dark switch and make an outlet named colorSwitch. Adding a comment to mark your outlets,  you should now have this in your code

 //MARK: - Outlets

@IBOutlet weak var colorSwitch: WKInterfaceSwitch!
@IBOutlet weak var navigationSwitch: WKInterfaceSwitch!

Now add an action for the button named goButtonPressed. Add an action from the Gray switch named navigationSwitchdidChange. Add an action from the color switch named colorSwitchDidChange. You should have the following when done:

@IBAction func navigationSwitchDidChange(value: Bool) {
}

@IBAction func colorSwitchDidChange(value: Bool) {
}

@IBAction func goButtonPressed() {
}

WatchKit is write only. There are no properties on the controls we can read.  We’ll need to store the switch state in the extension. Add two Bool values above the outlets:

var isGoingToGray = true
var isDarkColor = true

Change the code for navigation switchDidChange to this:

@IBAction func navigationSwitchDidChange(value: Bool) {
    if value{
        navigationSwitch.setTitle("Gray")
    }else{
        navigationSwitch.setTitle("Color")
    }
        isGoingToGray = value
}

We change our title and save our state. We do the same with the colorSwitchDidChange action. Change it to this:

@IBAction func colorSwitchDidChange(value: Bool) {
    if value{
        colorSwitch.setTitle("Dark")
    }else{
        colorSwitch.setTitle("Light")
    }
    isDarkColor = value
}

That is all setup for the go button, which will logically go to one of the two interfaces. It will also pass a Bool value to the destination controller.

Change the goButtonPressed to this:

 @IBAction func goButtonPressed() {
//prepare context
var myContext:Bool? = isDarkColor
//logical navigtion
if isGoingToGray {
pushControllerWithName("Gray", context: myContext)
}else{
pushControllerWithName("Color", context: myContext)
}

}

The important line here is the pushControllerWithName("Color", context: myContext) statement, which pushes a new controller onto the navigation stack.  We first prepare a value called a context to pass to the destination controller.  We check which interface we want, the color or gray one. We push that controller  onto the display stack using the storyboard identifier  instead of a segue to the watch. We also pass the Bool value to the destination.

Build and Run.  The switch logically selects the correct interface.

navigation hierarchy

We sent data to the destination controllers, but we didn’t do anything with it. In our next lesson, we’ll pass  and use data between controllers using the context.

One response to “Swift WatchKit: Introducing Navigation to the Apple Watch(Part 2: Hierarchical Interfaces)”

  1. […] our last lesson we set up navigation in the Storyboard and programmatically. We left off with passing data from one […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: