WatchKit: Let’s Create a Table

I can’t get enough of WatchKit. Sooooo much to learn! After staring with a simple Hello World app, I’ve moved on to building a Table-based WatchKit example:

WatchKit Table Example App

Here is how to make a Table with WatchKit:

Setup your Project

Walk through the steps I’ve outlined in my initial WatchKit post – How To Create A “Hello World” WatchKit App. Make sure the app is up and running!

Create a Table

In your Interface.storyboard, add a Table element:

WatchKit Table

Notice that each WKInterfaceTable row has a Table Row Controller. If you expand it, you’ll see a Group. Add a Label and an Image to the Group inside the Table Row Controller, and adjust the sizing as needed:

Create a Custom Table Row Controller

Since we’re going to have custom row elements, create a Table Row Controller. Despite it’s name, a Table Row Controller is actually an NSObject:

Table Row Controller NSObject

So you can create a your own custom NSObject, and subclass the Table Row Controller. To do that, just create a new NSObject file in your WatchKit Extension, and import WatchKit:


Now, you can subclass your Table Row Controller in the storyboard to this custom Table Row Controller:


Also make sure to add an identifier to your row:


Next, you can create an IBOutlet for your Image and Label:

Now, let’s populate some rows!

Create a Data Source

As with any Table, you need a data source. In my case, I’m going to create an array of minion names, whose image names match their names:


Load Table Data

Almost there! But first, don’t forget to create an IBOutlet for your Table in the InterfaceController:

We can now add the a loadTableData() function and call it in InterfaceController’s init:

LoadTableData WatchKit

With a few label and image sizing adjustments in Interface.storyboard, when you run the app, you can now see a pretty nice table of Minions!

Get the full source code on Github here!

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.

  • loopbum

    In the Project Folder “WatchKitTableDemo / WatchKitTableDemo WatchKit Extensions / Supporting Files / Info.plist” — There is NSExtension > NSExtensionPointIdentifier =

    An error is given after Build Completion: “An installation error occurred” — “This app contains an app extension that specifies an extension point identifier that is not supported on this version of iOS for the value of the NSExtensionPointIdentifier key in its Info.plist”

    My iPhone already has been updated to iOS 8.2 just fine, so I’m wondering if anyone else has run into this?


  • loopbum

    The Simulator is not showing up for me in XCode beta for some reason; just my iOS device, even when it’s no connected via USB. Shouldn’t the simulators be there? Thx

    • Not even the iPhone simulator shows up?

      • loopbum

        Oddly enough, only “iOS Device” shows up. When I try to run anyway w/o my device in it says “No supported iOS devices are available. Connect an iOS device to run your application or choose an iOS simulator as the destination.” (and there is no iOS simulator in the run pull down). I’ve Pulled this particular project from GitHub.

        • Have you tried going to Xcode -> Preferences -> Downloads and seeing if there are any Simulator downloads there? Super weird. Maybe re-download the beta?

          • loopbum

            I’m going to re-download. I examined the contents of the 6.2 beta and it had the iOS Simulator in it but that’s it. The preferences update just has 7.1 simulator and documentation. I’ll let you know if it helps; your examples and blog posts are very good; I’d like to get it working.

          • loopbum

            Download and reinstall worked.

          • Yay!

      • loopbum

        I thought I found a potential solution here, and instead of any, I chose iOS 8.2 simulator only, but still no fly,

  • fbara

    In the function loadTableData() I’m receiving an error on the line “minionTable.setNumberOfRows(minion.count, withRowType: “MinionTableRowController”)”

    The error is “unexpectedly found nil while unwrapping an Optional value”. I’ve gone thru my code and compared it to your code (downloaded from github) and I can’t find my error. I’m sure it’s something simple like a typo but I was wondering if you could give me an idea of where you think the error might be?


    • Did you add an identifier for MinionTableRowController in the storyboard? See “make sure to add an identifier to your row:” in this blog post.

      • fbara

        Thanks for the reply. Yes, I added the identifier. It’s something I did while coding but I just can’t find the mistake. I’ll either start the tutorial over again, and hope I catch the error, or just use your code as a base for continuing on. Thanks again!

        • quintonwall

          I’m sure you solved this by now, but just in case someone else hits a similar issue, I suspect the problem was fbara was using the swift file name in the withRowType param rather than the identifier name set up in the storyboard. In your sample (thanks btw!), the .swift file and identifier happen to be the same.

          • Aveia

            thanks 🙂

    • Jake

      The thing that got me was that I switched the screen size at the bottom of IB to 38mm then debugged in 42mm. Since I added my table with the 38mm option selected it apparently doesn’t add those elements to the 42mm version. Took me a good 2 hours to figure it out… from now on I’ll add all my components to the “Any Screen Size” version which will add it to both watch sizes.

  • Bryan Lloyd Anderson

    All I’m seeing is a blank screen on my watch simulator. Going through breakpoints the code seems to be working, but what could be the cause? I’ve followed step by step

    • Ezequiel Galindo

      I passed through this issue so I put loadTableData() method inside willActivate(). It works like a charm. I hope that it helps somebody.

  • kruherson

    Hello, I have a question about this watchkit table. How can I create on click event for selected row in table? Do you have any experience with this?

    I want to click on row and open a new interface with detailed view of selected row.

    Any help would be appreciated.

    Thank you

    • yogendra bagoriya

      Use this

      – (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex;

  • Kelly

    Thanks for the helpful post!

    I see for your screenshots the images are flush to the left edge of the Interface group. When I download the project the image is not flush to the edge. Did Xcode 6 beta 5 change something so it can’t look like that anymore?

    Thanks in advance!

  • Thanks for sharing this. It’s funny how simpler tables are in WatchKit, for the moment at least.

  • Rhodesie

    Great Article thanks!!

    Just FYI I had to put the loadTableData call into the “willActivate” function rather than the init as mentioned in the article or in the awakeWithContext function in the github source file.

    • Rich G

      Yeah, same goes, otherwise first four cells were not shown.

  • MikeTradr

    Neat Natasha, thank you. I’m new an learning… had to copy some of the png’s into images.xcassets. Works in simulator, woops well it did! not a wait spinner. On Watch same wait spinner. Anyone know why? It did show in simulator a minute ago! xcode 6.3.1 advice?

    • MikeTradr

      hey got it to work somehow! lol yeah! onward… thank you Natasha, my First Watch app is yours! 🙂

  • sn

    I’m getting a: Use of undeclared type ‘MinionTableRowController’ in the interface controller where I’ve tried to enumerate over the minions… What have I missed?

  • Ravi Maheshwari

    I am creating tableview but not getting proper alignment. orange is my table view. I dont understand why tableview is showing like this??

    Even i have added a label but it is not showing it too.

    so can you please help me why i am getting this ???

    thanx in advance

  • ramanan

    Is it possible to expand/collapse table row in wacthkit ?

  • PCharpentier

    I want to make a table of labels and a label side by side. I have two questions about it.

    Do you know if it’s possible to disable the scroll for the label ? Because now, all the screen move when I scroll and I want to have all the time my label centre in my screen.

    I have a second question about the focus. I saw that it will be possible to scroll to an index. Do you know if it’s possible to centre a row of the center of the screen ?

    Maybe it will be better to use picker for my needs but picker don’t allow user interaction and I have to add a button for validation.