Class

WKInterfaceController

A class that provides the infrastructure for managing the interface in a watchOS app.

Overview

An interface controller serves the same purpose as a UIViewController object in a UIKit app, except that it does not manage any actual views. It runs in your WatchKit extension and remotely manages the behavior associated with an interface controller in your Watch app’s storyboard file. You subclass WKInterfaceController and use its methods to configure the elements of your storyboard scene and to respond to interactions with those elements.

Your interface controller code runs locally on the user’s Apple Watch but is separate from the interface that it manages. When you change the value of an interface object in your code, the system forwards the needed information to your Watch app, which makes the corresponding changes onscreen.

Initializing Your Interface Controllers

When the user interacts with your app content, the system launches your extension and creates the appropriate interface controller objects automatically. Apps use different interface controllers to manage their glance, notification, and app interfaces. WatchKit uses the information in your app’s main storyboard file to determine which interface controller to load. Glance and notification scenes are configured specially so that the system can identify them. For your app, WatchKit loads your app’s main interface controller initially, but you may change the initial initial interface controller at launch time.

When creating an interface controller, WatchKit instantiates the class and calls its init() method followed shortly by its awake(withContext:) method. Use those methods to initialize variables, load data, and configure the items in your storyboard scene. If WatchKit passes a valid object to the awake(withContext:) method, use the information in that object to customize the initialization process.

The willActivate() method lets you know when your interface is active. Use the willActivate() method to perform any last minute tasks, such as checking for updates to your content. (Do not use it for your primarily initialization.) The willActivate method may be called at times when your interface is not yet onscreen. For example, WatchKit may call the method in advance so that you have time to update your content. WatchKit calls the didAppear() method to let you know when your interface becomes visible. Similarly, WatchKit calls the willDisappear() and didDeactivate() methods when your interface moves offscreen again.

In iOS Simulator, WatchKit calls the didDeactivate() method for the current interface controller when you lock the simulator by selecting Hardware > Lock. When you subsequently unlock the simulator, WatchKit calls that interface controller’s willActivate() method again. You can use this capability to debug your activation and deactivation code.

Displaying Your App’s Interface Controllers

Your Watch app may use one of two navigation styles for displaying content. The hierarchical navigation style lets you push and pop interface controllers similar to a navigation controller on iOS. The page-based style lets the user navigate between two or more interface controllers by swiping horizontally.

For page-based navigation, you normally specify the interface controllers for each page at design time. Once configured, you do not need to make any calls to facilitate navigation from page to page. WatchKit automatically displays the next page in the sequence when the user swipes horizontally. If you want to change the currently displayed pages, you can do so at any time by calling the reloadRootControllers(withNames:contexts:) class method. Typically, you call that method early in your app’s launch cycle but you may call it at any time to reload your interface.

For hierarchical interfaces, you are responsible for pushing new interface controllers onscreen in response to user actions. When you want to display new content, call the pushController(withName:context:) method and specify the name of the interface controller you want to display. WatchKit handles all of the animations associated with displaying the new interface controller.

When pushing a new interface controller, it is recommended that you pass a context object to the pushController(withName:context:) method. A context object is the main way to communicate information to the new interface controller. For example, you might use this object to specify the data that you want the new interface controller to display. A context object can be an existing data object, or it can be a dictionary that you create dynamically and fill with relevant information.

When using segues to initiate hierarchical navigation between interface controllers, WatchKit calls the contextForSegue(withIdentifier:in:rowIndex:) or contextForSegue(withIdentifier:) method based on whether the source of the segue was a table row or a button. Use those methods to provide the context object needed to initialize the new interface controller.

Presenting an Interface Controller Modally

Apps can present an interface controller modally to gather or display information. A modally presented interface controller animates up from the bottom of the screen and covers the current interface. Dismissing the interface reverses the animation and reveals the previously covered interface controller again. When presenting a modal interface, you can display a single interface controller (which is the most common use) or you can display multiple interface controllers in a page-based layout.

Use the presentController(withName:context:) and presentController(withNames:contexts:) methods to present your interface controllers modally. If the modal interface controller does not have a title, its title is set to the string Cancel by default. You can set the value of this string in your storyboard or change it at runtime using the setTitle(_:) method. When the user taps the title string, WatchKit automatically dismisses the modal interface without taking any further actions.

Presenting Standard System Interfaces

The system supports several standard interfaces for gathering input or displaying specific types of information.

The standard interfaces have built-in buttons so that the user can dismiss them at any time. Many of the interfaces also have a dismiss method that you can use to close the interface programmatically. While an interface is active, your app does not have direct control over the interactions with that interface. Use actions or a completion handler to handle any tasks related to the interface itself.

Interface Builder Configuration Options

Xcode lets you configure information about your interface controller in your storyboard file. Table 1 lists the attributes you can configure in your storyboard and their meaning.

Table 1

Interface controller attributes

Attribute

Description

Identifier

The name of the interface controller. Use this name to specify which interface controller to push or present.

Title

The title string assigned to the interface controller. You can set this value programmatically using the setTitle(_:) method.

Is Initial Controller

A Boolean indicating whether the object is the app’s root interface controller. Only one interface controller at a time may have this option enabled. This option does not apply to glance or notification interface controllers.

Display Activity Indicator When Loading

A Boolean indicating whether the interface controller’s contents should be hidden until after the willActivate() method returns. When this option is enabled, the system displays a progress indicator until the willActivate() method returns. You might disable this option if your interface contains mostly static information that can be displayed right away.

Always Bounce

A Boolean value indicating whether scrolling should always cause the screen to bounce, regardless of the length of your content. For content that does not require scrolling, you can enable this option to cause the bounce effect and show that your content does not need to scroll.

Background

The background image to be displayed behind the scene’s content. The image you specify in your storyboard scrolls with your interface controller’s content.

Mode

The content mode for the background image. This mode defines how the background image scales or fills the screen and behaves in the same way as the constants for the UIViewContentMode type.

Animate

A Boolean value indicating whether an animated background image starts running its animation automatically after being loaded. Set this option to Yes if you want the animation to start automatically; set it to No if you prefer to start the animation programmatically.

Color

The background color to be displayed behind the scene’s content.

Insets

The amount of space (in points) to insert between the edges of the interface controller and its content. Selecting Custom lets you specify different values for the top, bottom, left, and right edges.

Spacing

Additional spacing (in points) to include between items in the interface controller.

Table 2 lists the attributes you can configure for a glance interface controller.

Table 2

Glance interface controller attributes

Attribute

Description

Identifier

The name of the glance interface controller.

Display Activity Indicator When Loading

A Boolean value indicating whether the system displays a loading indicator for the glance. Glances display a snapshot of their pervious content until the willActivate() method returns. When this option is enabled, the system also displays a loading indicator and information about when the glance was last updated while the snapshot is visible. When this option is disabled, the system does not display those visual indicators.

Upper

The template to use in the upper portion of the glance. Select the template that best suits the information you want to display.

Lower

The template to use in the lower portion of the glance. Select the template that best suits the information you want to display.

Subclassing Notes

Subclass WKInterfaceController when you have a storyboard scene that requires configuration at runtime or that handles user interactions. Typically, you define a custom subclass for each unique storyboard scene that your app manages. In your subclass, define outlets for any interface objects you need to configure and define action methods for responding to interactions with the elements of your storyboard scene.

Most custom interface controllers you use in your app require a custom interface controller subclass. Even glances need an interface controller to update the glance contents. The only storyboard scene that cannot use a custom interface controller is the scene associated with a static notification interface. When implementing an interface controller for your dynamic notification interface, subclass WKNotificationInterfaceController instead.

Override any methods of the class needed to configure your interface and get it ready to display. Most interface controllers override the init() and awake(withContext:) methods. Override any other methods that make sense based on your needs.

Topics

Initializing the Interface Controller

init()

Returns an initialized interface controller object.

func awake(withContext: Any?)

Initializes the interface controller with the specified context data.

Responding to Activation and Appearance Events

func willActivate()

Called to let you know that the interface controller’s is active.

func didDeactivate()

Called to let you know that the interface controller is no longer active.

func didAppear()

Called to let you know that the interface controller’s content is now onscreen.

func willDisappear()

Called to let you know that the interface controller’s content is now offscreen.

Implementing a Navigation Interface

func pushController(withName: String, context: Any?)

Pushes a new interface controller onto the screen.

func pop()

Pops the current interface controller from the screen.

func popToRootController()

Pops all interface controllers except the app’s initial interface controller.

Presenting Interface Controllers Modally

func presentController(withName: String, context: Any?)

Presents a single interface controller modally.

func presentController(withNames: [String], contexts: [Any]?)

Presents a page-based interface modally.

enum WKAlertControllerStyle

Constants indicating the styles for standard system alerts.

func dismiss()

Dismisses the current interface controller from the screen.

Navigating a Page-Based Interface

class func reloadRootPageControllers(withNames: [String], contexts: [Any]?, orientation: WKPageOrientation, pageIndex: Int)

Loads the specified interface controllers and rebuilds the app’s page-based interface for the given scrolling orientation.

Beta
enum WKPageOrientation

Scrolling orientations for page-based interfaces.

Beta
class func reloadRootControllers(withNames: [String], contexts: [Any]?)

Loads the specified interface controllers and rebuilds the app’s page-based interface.

class func reloadRootControllers(withNamesAndContexts: [(name: String, context: AnyObject)])

Loads the specified interface controllers and rebuilds the app’s page-based interface.

func becomeCurrentPage()

Displays the interface controller in the page-based interface.

Managing Segue-Based Transitions

func contextForSegue(withIdentifier: String)

Returns the context object to pass to the specified interface controller when a button is tapped.

func contextsForSegue(withIdentifier: String)

Returns the context objects to pass to a page-based set of interface controllers when a button is tapped.

func contextForSegue(withIdentifier: String, in: WKInterfaceTable, rowIndex: Int)

Returns the context object to pass to the specified interface controller when a row in a table is tapped.

func contextsForSegue(withIdentifier: String, in: WKInterfaceTable, rowIndex: Int)

Returns the context objects to pass to a page-based set of interface controllers when a row in a table is tapped.

Scrolling

func scroll(to: WKInterfaceObject, at: WKInterfaceScrollPosition, animated: Bool)

Scrolls the specified object to the given position onscreen.

Beta
enum WKInterfaceScrollPosition

Onscreen scroll positions.

Beta
func interfaceDidScrollToTop()

Tells the interface controller that the user has performed a scroll-to-top gesture (for example, tapping the status bar) and that the scrolling animation has finished.

Beta
func interfaceOffsetDidScrollToTop()

Tells the interface controller that the user has scrolled to the top of the interface and that the scrolling animation has finished.

Beta
func interfaceOffsetDidScrollToBottom()

Tells the interface controller that the user has scrolled to the bottom of the interface and that the scrolling animation has finished.

Beta

Animating Changes to the Interface

func animate(withDuration: TimeInterval, animations: () -> Void)

Animates changes to one or more interface objects over the specified duration.

Handling Text Input

func dismissTextInputController()

Dismisses the text input controller without returning any text.

enum WKTextInputMode

The input modes supported by the text input controller.

Presenting Video and Audio Interfaces

Media Player Options

Keys indicating media playback options.

func dismissMediaPlayerController()

Dismisses the media interface controller.

enum WKAudioRecorderPreset

Constants indicating the quality of audio recordings.

Audio Recording Options

Options to specify when recording audio.

func dismissAudioRecorderController()

Dismisses the audio recording interface controller.

Handling Table-Row Selections

func table(WKInterfaceTable, didSelectRowAt: Int)

Called to let you know that the user selected a row in the table.

Managing Pickers

func pickerDidFocus(WKInterfacePicker)

Called to let you know that the specified picker is now receiving input from the Digital Crown.

func pickerDidResignFocus(WKInterfacePicker)

Called to let you know that the specified picker is no longer receiving input from the Digital Crown.

func pickerDidSettle(WKInterfacePicker)

Called to let you know when the user settles on a value in a picker.

Getting the Crown Sequencer

var crownSequencer: WKCrownSequencer

The object to use when directly tracking crown events.

Configuring the Context Menu

func addMenuItem(with: WKMenuItemIcon, title: String, action: Selector)

Adds an action to the context menu using a system-provided icon.

func addMenuItem(withImageNamed: String, title: String, action: Selector)

Adds an action to the context menu using an existing image resource in your Watch app bundle.

func addMenuItem(with: UIImage, title: String, action: Selector)

Adds an action to the context menu by using an image provided by your WatchKit extension.

func clearAllMenuItems()

Removes all programmatically added actions from the context menu.

enum WKMenuItemIcon

Template images that you can use for menus.

Setting the Display Title

func setTitle(String?)

Sets the title of the interface.

Coordinating Handoff Activity

func updateUserActivity(String, userInfo: [AnyHashable : Any]? = nil, webpageURL: URL?)

Registers the current activity of the Watch app with the system.

func invalidateUserActivity()

Invalidates the most recent user activity.

Adding PassKit Passes

func presentAddPassesController(withPasses: [PKPass], completion: () -> Void)

Displays a modal interface for presenting passes to the user.

func dismissAddPassesController()

Dismisses the pass interface controller

Getting the Interface Dimensions

var contentFrame: CGRect

The frame rectangle used to display your app’s content.

Managing Glance Updates

func beginGlanceUpdates()

Tells the system that you are about to start a potentially lengthy update task for your glance.

func endGlanceUpdates()

Tells the system that you finished updating your glance content.

Notifications

let WKAccessibilityVoiceOverStatusChanged: String

Posted by WatchKit when VoiceOver starts or stops. This notification does not include a parameter.

static let WKAccessibilityReduceMotionStatusDidChange: NSNotification.Name

Posted by WatchKit when reduced motion is enabled or disabled. This notification does not include a parameter.

Beta

watchOS 1 Methods

func handleAction(withIdentifier: String?, for: UNNotification)

Delivers a notification payload and a user-selected action to the interface controller.

class func openParentApplication([AnyHashable : Any], reply: (([AnyHashable : Any], Error?) -> Void)? = nil)

Sends data from your WatchKit extension running in watchOS 1 to your iOS app.

Deprecated Symbols

func presentController([(name: String, context: AnyObject)])

Presents a page-based interface modally.

func handleAction(withIdentifier: String?, forRemoteNotification: [AnyHashable : Any])

Delivers a remote notification payload and a user-selected action to the interface controller.

Deprecated
func handleAction(withIdentifier: String?, for: UILocalNotification)

Delivers a local notification payload and a user-selected action to the interface controller.

Deprecated
func handleUserActivity([AnyHashable : Any]?)

Responds to Handoff–related activity.

Text Response Key

Keys for retrieving text response information.

Relationships

Inherits From

Conforms To

See Also

User Interface Basics

class WKInterfaceObject

An object that provides information that is common to all interface objects in your watchOS app.

class WKAlertAction

An object that encapsulates information about a button displayed in an alert or action sheet.

class WKAccessibilityImageRegion

An object that defines a portion of an image that you want to call out separately to an assistive app.

func WKAccessibilityIsVoiceOverRunning()

Returns a Boolean value indicating whether VoiceOver is running.

func WKAccessibilityIsReduceMotionEnabled()

Returns a Boolean value indicating whether reduced motion is enabled.

Beta

Beta Software

This documentation contains preliminary information about an API or technology in development. This information is subject to change, and software implemented according to this documentation should be tested with final operating system software.

Learn more about using Apple's beta software