Apple Watchの画面遷移

これはWatchKit Advent Calendar 2014の22日目の記事です。

WKInterfaceControllerの生成

WKInterfaceControllerは、現時点のWatchKitではStoryboard上でしか作ることができません。

iOSのUIViewControllerは、Storyboardやxibを使わなくても、コード上の記述のみで作成することができました。

    UIViewController* newViewCon = [[UIViewController alloc] init];

WKInterfaceControllerもコードで生成することができないわけではありません。 下記のように書くと、オブジェクトが生成され、メモリも確保されています。

    WKInterfaceController* watchCon = [[WKInterfaceController alloc] init];

ただ、実はここで生成したWKInterfaceControllerのインスタンスを画面上に表示する手段がありません。 Watch Kitでは、画面遷移を行うすべてのメソッドで、Storyboard IDを指定してオブジェクトを生成するため、上記のように生成したオブジェクトを画面に表示する術がないのです。

Watch Kitの画面遷移

WKInterfaceControllerを表示するには、PushとModalの二つのタイプがあります。 どちらもiOSのPushとModalとほぼ同じ意味で使われるます。

iOSのTabViewControllerにあたる画面遷移はありません。

awakeWithContext

PushやModalで画面を表示するときには、awakeWithContextで表示する画面へ引数を一つ渡すことができます。 NSStringでもNSArrayでもNSDictionaryでもなんでも渡すことができるので、この引数で画面に表示する要素などを設定することができます。

Pushでの画面表示

まず、Pushでの画面表示ですが、WKInterfaceControllerのpushControllerWithNameで行います。 例えば下記のコードでは、人物の情報を表示するWKInterfaceController(storyboard上のIDがpeoplescreen)を作成し、その画面に人物の情報を含むNSArrayを引数として渡しています。

受け取った側のWKInterfaceControllerでは、awakeWithContextの引数としてこのNSArrayが取得できるので、画面に 「name: Alice」や「tel:03-1234-5678」などの表示をすることが可能です。

    NSArray* contexts = @[ @{@"name":@"Alice"},
                           @{@"tel":@"03-1234-5678"}];

    [self pushControllerWithName:@"peoplescreen" context:contexts];

また、Pushで表示された画面は、左上の画面タイトルエリアが自動的にボタンに設定されて、押すと1画面戻るようになっています。 iOSのように「戻る」ボタンを自分で実装する必要はありません。

Modalでの画面表示(単数)

Modalでの画面表示は、1枚の画面を表示する場合と複数の画面を表示する場合で異なります。 1枚の画面を表示する場合は、呼び方はpushの場合とほぼ同様です。

左上のタイトルエリアは自動的にcloseボタンとなります。

下記のコードでは、人物の情報を表示するWKInterfaceControllerを作成し、その画面に人物の情報を含むNSArrayを引数として渡しています。

    NSArray* contexts = @[ @{@"name":@"Alice"},
                           @{@"tel":@"03-1234-5678"}];

       [self presentControllerWithName:@"peoplescreen" context:contexts];

Modalでの画面表示(複数)

Modalで複数の画面を表示する場合には、1枚の画面を表示する場合とは違うメソッドを使います。 第一引数としては、よびだす画面の Storyboard IDをNSArrayとして渡します。

また、contextとして渡す引数もNSArrayになり、表示する画面の数と同じ要素数を持つようにしてください。

表示されるWKInterfaceControllerでは、contextとして渡された引数の一部が渡されます。 下記のコードの場合、"peopleController"と"companyController"と"placeController"の3枚の画像が表示されますが、1枚目の画面には、「@{@"name":@"Alice"}」のNSDictioanry、2枚目の画面には「@{@"tel":@"03-1234-5678"}」のNSDictionary、3枚目の画面には「@"Osaka"」のNSStringが渡されます。

    NSArray *controllerPersons = @[@"peopleController",
                                   @"companyController",
                                   @"placeController"];
    NSArray* contexts = @[ @{@"name":@"Alice"},
                           @{@"tel":@"03-1234-5678"},
                           @"Osaka"];
    [self presentControllerWithNames:controllerNames contexts:contexts];