Welcome to the 8th technical blog in our Apple Watch series. Last time we looked at the issues we faced when trying to introduce multiple row types into an Apple Watch table. Another learning curve we faced when creating the Whiskr Apple Watch App was how to use a context menu with modal dialogs. We ideally wanted this menu to display when the user force touched (long press) on a cat picture, so they could chose between showing where the picture was taken on a map, or display additional information about the picture, for example who took it.
The context menu inside the Whiskr app when you force press on a photograph.
1. Context Menu
The first thing we needed to do was to open our storyboard. We need to drag a “menu” object out onto the Interface Controller that the user will force touch on. It’s worth noting here, that a context menu is unique only to a screen, you can not make it unique for each item in a table row for example.
After you have your context menu in place, it should automatically give you one menu item. You can either add more items by dragging them from the object library, or increment the item count in the menu inspector. You can also change the text and image for each menu item if you select a menu item and view the inspector.
You can see the menu on the interface controller on the left
2. Context Menu Tap Gesture
If you run your project now, and force touch on the screen you’ve set up your menu you’ll see all the items appear but they just won’t do anything yet! You can set up menu item tap gestures much like you’d set up a regular button. Open up the accompanying Interface Controller .m file and drag an outlet between the interface and code. You should do this for each of the menu items you have. e.g.
- (IBAction)menuMapPressed {
NSLog(@"map item pressed");
}
You should now be able to run your project again, and watch in the console for when each menu item is tapped.
3. New Interface Controller
If we now want to display a modal dialog when the user clicks one of our menu items, we first need to drag out a new Interface Controller in our Storyboard. However, we do not need to create a segue between the two screens yet! Instead we need to give the Interface Controller an identifier in the inspector window. We can then use this in the controller code to present a specific controller like so:
[self presentControllerWithName:@"ModelMapController" context:nil];
note the interface controller’s identifier
4. Passing data
The final piece of the puzzle for Whiskr was to pass data between the photograph page, and the map page (the actual location). You can only send 1 object which could contain multiple objects in the presentControllerWithName call. We’re going to send a photograph object.
As we’re sending our object as part the “context”, we can read it at the other end in theawakeWithContext:(id)context
function. We should then check the context is the type of object we’re expecting, and if it is then we can then use it. e.g.
if ([context isKindOfClass:[NSDictionary class]]) {
NSDictionary *photo = context;
}
Conclusion
This is one of the first major differences (after tables) we came across whilst building Whiskr. Hopefully, it helps demonstrate how to create a modal dialog more easily in your own Apple Watch apps. Next we’re going to look into how we shared data between the iPhone and Apple Watch app.