Mobile Technology

7. TECH: How to Add Multiple Row Types in an Apple Watch Table

Date Published:

This is the 7th blog in our Apple Watch blog series documenting our experiences in building an Apple Watch app. If you need to catch up, you can see our first post ‘What is the Apple Watch?’ here.

Since we now have our Whiskr app project set up one of the first interface items you might be using is a table. There are a lot of blog posts on how to get started with tables however one of the things we wanted to do with Whiskr was to use multiple types of rows in a single table e.g. we have a loading row, a heading row, and a content row. This blog will help you use several types of rows in your app too!

Imgur
a heading, and content row as displayed in our Whiskr app

1. Interface Builder

Firstly, we want to open the Apple App Storyboard (found in the WatchKit App folder). You should have an interface controller with a table in it. To create different types of rows you need to add more rows by selecting the table and in the inspector increase the number of rows. This will give you an empty row with a group in it. You can then drag out labels or images as you need.

Imgur

how to increase the number of rows in your table

2. Subclasses

Next, we need to create a class for each of our rows, they’ll want to be a subclass of NSObject. You’ll need to remember to set the class for each of the row and hook up your outlets. This will then allow you to change the text or images programmatically. For example, in Whiskr I can change the heading row to be the closest city or town name.

3. View Controller

Finally, inside our Interface Controller code that looks after our table we can create an array which will contain our row classes in the order want them. For example in Whiskr we have 1 heading row, followed by 20 photo rows, like so:

//add our heading row
[controllers addObject:@"HeadingRow"];

//add a row for each item in colour titles
for (NSString *i in _colourTitles){
    [controllers addObject:@"ColourRow"];
}

//set the row types
[_table setRowTypes:controllers];

Next, we can then loop through each row in our table and set the data that we want. E.g. I know the first item will be my heading row, so I can cast it like this:

//set the headline
DEV_HeadlineRow *rowHeadline = [self.table rowControllerAtIndex:0];
[rowHeadline updateText:@"Bristol"];

For the remaining photo rows I can update the label to show how far away they are from my current location:

int i = 1; //starts at 1 because heading row is 0

//loop through each photo in my photos array
for(NSDictionary *photo in _photos){

    //get the row
    DEV_PhotoRow *row = [self.table rowControllerAtIndex:i];

    //set the values
    [row setRowWithTitle:[NSString stringWithFormat:@" %@ meters",photo[@"distance"] ] 
        andImage:[UIImage imageNamed:@"cat_icon_watch_black"] 
        andIsCalviumRow:NO];

    //increment the row index counter
    i++;
}

Conclusion

I’ve done it this way as I know exactly whereabouts my rows are going to be, however you could loop through each row and check what type of class it is before setting the value programmatically. But hopefully this helps to demonstrate how to go about setting up multiple row types in a single table.