Guides and Sample Code

Developer

App Programming Guide for watchOS

On This Page

Interface Objects

Your WatchKit extension manipulates your Watch app’s UI using interface objects. An interface object is an instance of the WKInterfaceObject class, or more specifically one of its subclasses. Interface objects are not views. They are proxy objects for the actual views presented by your Watch app. The WatchKit framework provides interface objects for most (but not all) of the visual elements you can add to your storyboard scenes.

Creating an Interface Object

You create interface objects indirectly by adding the object to your storyboard scene and referring to it from your interface controller. After adding an element to your storyboard, create an outlet for it in your interface controller. During the initialization of your interface controller, watchOS creates the interface objects for all of your connected outlets automatically. You never create the interface objects yourself.

To create an outlet for an interface object, create a declaration similar to the following in your interface controller:

Objective-C

  1. @interface MyHelloWorldController()
  2. @property (weak, nonatomic) IBOutlet WKInterfaceLabel* label;
  3. @end

Swift

  1. class MySwiftInterfaceController {
  2. @IBOutlet weak var label: WKInterfaceLabel!
  3. }

Connect each outlet to the corresponding item in your storyboard. A quick way to create property declarations and connect them to an item is to use the assistant editor in Xcode. To create an outlet, display the assistant editor and control-drag from an interface object to the interface definition of your class. (In Swift, drag to your class definition.) Xcode prompts you to specify the outlet’s name before creating an appropriately configured property with the IBOutlet keyword.

Configuring Your Interface at Design Time

At design time, configure the interface objects in each storyboard scene using Xcode. Many layout-related attributes can only be configured at design time. For example, you can change a label’s text, color, and font using a WKInterfaceLabel object, but you cannot change the number of lines or the minimum scale factor. Those attributes must be configured in Xcode, as shown in Figure 8-1.

Figure 8-1Configuring a label object image: ../Art/formatted_text_attributes_2x.png

For more information about how to configure interface objects, see the classes for your interface objects in WatchKit Framework Reference.

Changing Your Interface at Runtime

In the code of your WatchKit extension, you update your app’s user interface by calling methods of any referenced interface objects. An interface controller may change the configuration of its interface objects only while it is active, which includes initialization time. In your init, awakeWithContext:, and willActivate methods, call methods to assign data values to labels, images, and other objects in your user interface. You might also update them from your interface controller’s action methods.

At initialization time, it is important to let the system initialize your interface controller class before doing anything else. The initialization methods of WKInterfaceController and its subclasses are where watchOS creates your app’s interface objects. So any initialization code you write for your interface controllers must call the super implementation first. Listing 8-1 shows an example of an init method for an interface controller that contains an outlet (called label) for a WKInterfaceLabel object.

Listing 8-1Initializing an interface controller

Objective-C

  1. - (instancetype)init {
  2. // Always call super first.
  3. self = [super init];
  4. if (self){
  5. // It is now safe to access interface objects.
  6. [self.label setText:@“Hello New World];
  7. }
  8. return self;
  9. }

Swift

  1. override init() {
  2. // Initialize properties here.
  3. super.init()
  4. // It is now safe to access interface objects.
  5. label.setText("Hello New World")
  6. }

The WatchKit framework optimizes any attempts to set values on your app’s interface objects. Whenever you set the values for one or more interface objects in the same run loop iteration, the new values are coalesced and transmitted to the Watch app in a single batch. Coalescing changes means that only that last change to a given property of an object is sent to the device. More importantly, setting the same property to the same value generates a log message to help you track down the duplicate calls.

For information about the methods you use to configure your interface objects, see the corresponding class descriptions in WatchKit Framework Reference.

Responding to User Interactions

Use buttons, switches, and other interactive controls to initiate changes in your app. When a button is tapped or the value of another control changes, watchOS calls the associated action method in your interface controller. Each type of interface object has a required format for its action method, which are listed in Table 8-1. Change the name of the action methods to something appropriate for your app.

Table 8-1Action methods for interface objects

Object

Objective-C

Swift

Button

- (IBAction)buttonAction

@IBAction func buttonAction()

Picker

- (IBAction)pickerAction:(NSInteger)index

@IBAction func pickerAction(index: Int)

Switch

- (IBAction)switchAction:(BOOL)on

@IBAction func switchAction(value: Bool)

Slider

- (IBAction)sliderAction:(float)value

@IBAction func sliderAction(value: Float)

Menu Item

- (IBAction)menuItemAction

@IBAction func menuItemAction()

Interfaces can use segues or the table:didSelectRowAtIndex: method of the interface controller to respond to taps in a table row. Use a segue to display another interface controller. Prior to performing the segue, watchOS calls the contextForSegueWithIdentifier:inTable:rowIndex: or contextsForSegueWithIdentifier:inTable:rowIndex: method of your interface controller so that you can specify the context objects to use when displaying the interface controller. If you use the table:didSelectRowAtIndex: method instead of a segue, you can perform whatever actions are appropriate for tapping on the row.

After your interface controller is initialized and onscreen, watchOS calls the methods of your interface controller only when the user interacts with your interface. If you want to update your user interface without user intervention, you must configure an NSTimer object and use its handler to perform any needed tasks.

Hiding Interface Objects

Hiding objects lets you use the same interface controller to display different types of content. Each scene in your storyboard file must contain all of the interface objects needed to display its content at runtime. If you customize your interface based on the data you have available, you can hide objects that you do not need. When you hide an object, you effectively remove it from your interface. During layout, hidden items are treated as if they were removed entirely from the layout. To hide an object, call its setHidden: method and pass the value YEStrue.