Linking Interfaces in Your Storyboard

There are several ways to go from one interface controller to another. You’ll see them as the chapter goes on, but one thing to note right away is that whether you’re performing the transition in code or linking it up in Interface Builder, every interface controller must have its user interface laid out in your storyboard file. Unlike your iPhone app, where you can create view objects from code, from a storyboard, or from a xib, every single UI element needs to exist in your storyboard before it’s referenced.

Another departure from UIKit on iPhone is that WatchKit includes a built-in way to pass context from one interface controller to another. The context you pass can be model objects, raw data, or nothing at all, but the ability to send this context is a nice way to distribute data without having to implement new methods in each view controller. You’ll see just how handy this can be later on, when you structure your app. For now, let’s look at the simplest way to move from one screen to another: linking them together in the storyboard. You don’t even need to write any code!

One of the simplest ways to navigate an iPhone app is to use UINavigationController to create a hierarchy of view controllers, the topmost of which is onscreen. You push a new view controller onto the stack to display it, and you pop it off to go back (or when your user taps the Back button). This is a well-understood way to dive into hierarchical data, and it’s easy to implement on the watch, as well. Let’s try it out.

Pushing an Interface Controller

Open the TapALap app’s storyboard. To make it easy, drag your interface controllers around so that your Go Running interface controller is to the left of your Run Log interface controller. Drop a new WKInterfaceButton onto your Go Running interface controller and title it “Run Log.” You want this button to open the run log, so Control-drag from the button to your Run Log interface controller. When you release the mouse button, a pop-up named Action Segue will appear, with two choices for the type of segue you’d like to create: Push or Modal. Consult the images here to make sure you’ve connected it properly:

images/TapALap-first-segue.png

To achieve the navigation controller--like effect, choose Push. This causes your interface controller to “push” the new interface controller onto the stack. Run your project with R to see how it works. When you run your app, it should look like the image here. The left-facing chevron indicates that there’s an interface controller to return to; tapping it or swiping left to right from the watch’s edge will return to the original one. Try it out both ways!

images/TapALap-push-segue-pushed.png

Using just this knowledge, you can already create pretty complicated interfaces. It’s fairly common for iPhone apps to drill down several layers deep in a hierarchy to get to the data you want to interact with, but with the limited screen real estate and interaction model of Apple Watch, you should use restraint. Nobody wants to page back through five layers of interface controllers on their wrist. When used appropriately, however, pushing new interface controllers makes a convenient, understandable structure of your interface controllers. This Run Log button seems unnecessary for your app, though, doesn’t it? Let’s try a different way of linking these together so that the user doesn’t even need to push a button to go from one to another.

Using Paged Interface Controllers

If you look at the list of Glances on your watch, you’ll see that each one is on its own screen, and to navigate between them you simply swipe left or right. There’s a page indicator on the bottom of the screen to show you which page you’re on, and it’s another familiar interface for iPhone users. WatchKit, however, doesn’t require you to use UIPageViewController and its cumbersome data source methods. Instead, you can lay out your interface controllers in the storyboard and get both the ability to swipe between them and the automatically updating page indicator for free—and still without writing a single line of code!

Head back to your storyboard and delete the Run Log button. You never needed it anyway. Notice that arrow pointing to your Go Running interface controller? That signifies that this is the first interface controller to be loaded when your user starts the watch app. To set up paging between view controllers, you don’t need to add a new, higher-level interface controller or add any fancy structure to the app. Simply Control-drag from the Go Running interface controller to the Run Log interface controller, just as you did for the button. Now, however, the list of possible segues is different; its title is Relationship Segue, and the only option is Next Page. Select it and your interfaces will be linked together, as shown in the image.

images/TapALap-next-page-segue.png

Build and run the app, and notice that you now have a page indicator on the bottom of the screen. Swipe right to left and you’ll see your Run Log interface (see the right side of the same image), no extra work required.

This is much better for what you’re trying to accomplish with your app. You want the default screen to be Go Running, since that’s what most users will open the app to do, but you also want to have the log quickly accessible. You could have stuck with the Run Log button, but a hierarchical interface implies some kind of ownership or parent-child relationship between the two controllers. That kind of relationship doesn’t exist between these two interface controllers. Since they make more sense as siblings than as a parent and child, you put them side-by-side and let the user navigate freely.

All is not rosy in the world of paged and pushed interface controllers, however. To illustrate, let’s add the next interface controller to your interface. From the Run Log interface controller, you want to view a run’s details when the user taps it. When that happens, you want to display a new interface controller with that run’s details. We’ll cover getting the run details set up later in this chapter,, but for now we can tackle presenting the interface.

Drag a new interface controller into your storyboard. Give it the title “Run Details.” Next, create a new WKInterfaceController subclass for it called RunDetailsInterfaceController. You don’t need to set anything up yet, so you can leave it as the stock Xcode template. Head back to the storyboard and enter RunDetailsInterfaceController into the new interface controller’s Class property in Xcode’s Identity Inspector.

As with the first transition you made, you want the Run Details interface controller to appear when the user taps. This time, however, you want the tap to be on a row in the table, not a button. To accomplish this, Control-drag from the run log’s row-controller object to the Run Details interface controller. This will connect the individual row—and therefore the individual run—to the new interface controller. Also like before, select Push for your segue. You’ll now have three interfaces lined up, as in the image here.

images/TapALap-invalid-push-segue.png

Build and run the app. You can still page from one interface controller to the next, as before. Tap a row in the Run Log interface controller and nothing happens. What have you done wrong? As it turns out, these two types of interface navigation are mutually exclusive. You can’t push into a paged interface controller, nor can you push from one. If you think about it, it makes sense—if you swiped left to right to go back from a pushed interface controller to paged interface controllers and then swiped in that same direction, you’d be navigating between pages, not going back. Whereas paging and pushing—on their own—are well-understood navigation idioms on both the watch and other iOS devices, mixing the two is not and can cause confusion on your users’ part. Fortunately, WatchKit won’t let you do this.

So how are you supposed to display these run details? You don’t want to add a new interface controller to your existing pages for every run the user takes. Eventually that would become impossible to navigate. You also don’t want to return to pushing the run log from the Go Running interface controller; we’ve already established that the paging interface is better. Fear not! There’s a third option: you can present the details modally.

Presenting Modal Interfaces

Let’s go back to the storyboard. Instead of deleting the segue, you can simply change its type. Click the segue that links the Run Log and the Run Details interface controllers and open Xcode’s Attributes Inspector. In the drop-down labeled Segue, you can change the type. Select Modal, and the segue’s icon will change. It should now look like the following image. Build and run the app, and you should see the Run Details interface controller appear when you tap a row in the Run Log interface controller.

images/TapALap-modal-segue.png

Modal interface controllers look slightly different than the other variety. For one, the title is stark white instead of the usual gray. Second, the time has disappeared from the status bar and the page indicator is gone. In fact, as you can see in the image here, the interface controller is pretty bare:

images/TapALap-bare-modal-presentation.png

This modal presentation isn’t quite as user friendly as the previous two presentation styles. The title is white to indicate that it’s turned into a close button; tap it to dismiss the interface controller. To make this clearer to the user, let’s do one final tweak: select the Run Details interface controller in your storyboard, open the Attributes Inspector in Xcode, and delete its title. Build and run again, and you’ll notice that WatchKit, in the absence of a title, chooses Cancel. This is appropriate for when you’re presenting a modal interface controller to perform an action, but since you’re just displaying data, Cancel doesn’t have much contextual meaning. Change the title to Close, and you’ll be more closely describing what’s actually happening.

While modal interface controllers have their caveats, they can be pretty important in your watch app. Whether you need to break out of a paged interface to present some information, present pages of information from within a pushed hierarchy, or interrupt the user so she can perform an action, a modal interface controller is sometimes necessary.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.96.163