仕事で WatchKit を使って Apple Watch の対応をしたりしています。

WatchKit で提供されているクラスの数が少ないのであまり悩んだりはしないのですが、テーブル関係で少し手こずったのでメモ。

テーブルを更新する

UITableView では、- reloadData が更新用のメソッドとして用意されていますが、WKInterfaceTable にはそのようなメソッドは用意されていません。

ですので、- reloadTable メソッドを WKInterfaceController のサブクラスに実装し、テーブルの表示を更新する情報が取得 (または更新) できた段階で呼びます。

- (void)reloadTable {
    if (!_resources) {
        return;
    }

    [self.table setNumberOfRows:_resources.count withRowType:@"TableRowIdentifier"];
    [_resources enumerateObjectsUsingBlock:^(Resource *resource, NSUInteger idx, BOOL *stop) {
        dispatch_async(dispatch_get_main_queue(), ^{
            TableRow *row = [self.table rowControllerAtIndex:idx];
            [row setTitle:resource.title];
        });
    }];
}

なんとなくわかると思いますが、_resources はテーブルの行ごとに必要なデータが格納された NSArray 型のオブジェクトと考えてください。

名前がややこしいのですが、WKInterfaceTable- setNumberOfRows:withRowType: メソッドの rowType は、Row Controller の Identifier を入れる必要があります。適当な値をセットするとセルのオブジェクトが取得できません。 (上記のサンプルだと TableRow *row の値) UITableViewCell- dequeueReusableCellWithIdentifier: と同じと考えるとよいと思います。

テーブルのセルをタップした時のアクション

WKInterfaceController- table:didSelectRowAtIndex: というメソッドがあるので、それをオーバーライドします。UITableViewDelegate のようなものがないので、どうやるかと悩んでしまいました。

テーブルのセルをタップして次の View (WKInterfaceController) に値を渡す

これは、Table の Row Controller と遷移先の View を Segue でつないで画面遷移をするときの話です。iOS でいえば - prepareForSegue:sender: にあたるものですね。

WatchKit では、- contextForSegueWithIdentifier:inTable:rowIndex: を使います。テーブルを使わない (タップしたセルの行が必要ない) 場合は - contextForSegueWithIdentifier: を使います。

- prepareForSegue:sender: を使う場合、遷移先の UIViewController のサブクラスを取得してプロパティなどを使って値をセットする形でしたが、WatchKit の場合は戻り値で渡す形になります。

- (id)contextForSegueWithIdentifier:(NSString *)segueIdentifier inTable:(WKInterfaceTable *)table rowIndex:(NSInteger)rowIndex {
    if ([segueIdentifier isEqualToString:@"goNextView"]) {
        Resource *resource = _resources[rowIndex];

        return resource;
    }

    return nil;
}

値を受ける時は、WKInterfaceController- awakeWithContext: メソッドの引数で受けます。

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];

    if (!context) {
        return;
    }

    Resource *resource = (Resource *)context;
    self.rowLabel = resource.title;
}

参考

Apple Watch Programming Guide: Tables https://developer.apple.com/library/ios/documentation/General/Conceptual/WatchKitProgrammingGuide/Tables.html#//apple_ref/doc/uid/TP40014969-CH14-SW5