How to navigate from one page set to another in WatchKit
Navigating between Storyboard layouts when supporting watchOS 6
by Lou Franco
In the last article we learned about page-based navigation on an Apple Watch. It's trivial if you are targeting watchOS 7, but in watchOS 6, WatchKit didn't use SwiftUI for the entry-point of the app and you still needed Storyboards to define pages.
If you are targeting watchOS 6, and you have several possible root views, then you define each in a Storyboard and you need to navigate between them outside of SwiftUI.
Example of a watch app with multiple root views
The Workout app on your watch is an example of an app that needs this kind of UI. In fact, pretty much any workout app would probably do it this way, and my own app, Sprint-o-Mat uses it as well.
When you start a workout app, you usually have a UI that shows you all of the possible workouts you could do and interacting with them lets you set them up.
In Sprint-o-Mat, it looks like this when you are setting up a workout (this uses a List and NavigationLinks as described in this article)
But, then when you start a workout, the UI changes to a page-based navigation structure that only has screens that let you interact with the workout itself.
And, when the workout is done, it navigates back to the initial root view.
How to change the root pages
In the last article, I showed how you create HostingController
classes for each page and how to connect them to the Storyboard.
In Sprint-o-Mat, the three pages that are shown during a workout are called WorkoutActionHostingController
, WorkoutHostingController
, and NowPlaying
. When you start a workout, I need to call WKInterfaceController.reloadRootPageControllers()
to reset the root to these pages. Here is the full call
WKInterfaceController.reloadRootPageControllers(
withNames: ["WorkoutActionHostingController", "WorkoutHostingController", "NowPlaying"],
contexts: [pageContext, pageContext],
orientation: .horizontal,
pageIndex: 1)
This says to load the three pages and provide the first two with pageContext
objects. The pages are horizontally laid out (so that you navigate with left and right swipes), and the workout page (at index 1) is the initial screen.
In my app, pageContext
holds all of the information needed to actually do the workout. The media player screen doesn't need it.
Navigating back is similar:
WKInterfaceController.reloadRootPageControllers(
withNames: ["MainHostingController"],
contexts: [context],
orientation: .horizontal,
pageIndex: 0)
When I actually start a workout, there's a countdown animation to give you three seconds to get ready to run. I'll show you how to do that in the next article.
Subscribe to be notified of the next WatchKit article
Make sure to sign up to my newsletter to get notified when a new article is published.
Contact me if you are working on a Watch app and need help.