2015年

4月

04日

Apple Watch Table View (テーブル一覧)の作成

Apple Watch Table View (テーブル一覧)の作成方法

Xcode 6.2 以上
https://developer.apple.com/xcode/downloads/
6.2からAppleWatch開発環境(watchkit)が入っています。

iOS8.2以上 (iPhone)
8.2にバージョンアップするとアプリ「Apple Watch」が追加されるのですぐわかります。


iPhoneアプリケーション プロジェクトを生成
xcode起動後、「Create a new Xcode project」を選択します。
次にiOS -> Application -> Single View Applicationを選択します。

 

プロダクト名をWatchKitAnimation01とします。


Watch Kit Appを追加
Watch Kitを追加します。File -> New -> Target を選択します。

 

AppleWatch ->WatchKit Appを選択します。


Include Glance、Include Notification Scene は、今回使わないのでチェックを外す。

Finishiをクリックします。

 

Activateをクリックします。

 

WatchKitフォルダーが追加されます。

WatchKitTableApp01Tests

WatchKitTableApp01 WatchKit Extension

WatchKitTableApp02 WatchKit App


テーブル用クラスの作成

右クリックでFile 一覧を出し「 New File...」を選択します。


iOSの「Source」から「Cocoa Touch Class」を選択し「Next」をクリックします。


WatchKitでテーブルを表示する場合は、UITableViewではなくWKInterfaceTableというクラスを使います。


まずは、画面のViewControllerのクラスを作成します。
WatchKitなので、WKInterfaceControllerを使います。

WKInterfaceControllerを継承したTableInterfaceControllerというクラスを作ってみます。

Nextをクリックします。


WatchKitのStoryboard上に配置されているInterfaceControllerのCustom Class名を変更します。


Custom Class -> Class一覧から作成した「TableInterfaceController」を選択して置き換えます。


Storyboard上のそのWKInterfaceControllerの上に、「Table」オブジェクト(WKInterfaceTable)を配置します。


Storyboard上のそのWKInterfaceControllerのオブジェクト上のWKInterfaceTableと、クラスのWKInterfaceTable propertyを接続します。

 

行表示のカスタムクラスを作成します。

右クリックでFile 一覧を出し「 New File...」を選択します。


iOSの「Source」から「Cocoa Touch Class」を選択し「Next」をクリックします。


Class名は「TableRowController」にしSubclassは、「NSObject」を選択します。


TableRowController.h

TableRowController.m

が追加されます。

 

行要素のカスタムクラスに、作成したNSObjectの継承クラスTableRowControllerを設定します。

 

Tableオブジェクト(WKInterfaceTable)の上にImageオブジェクトを配置します。


Tableのなかに、「Label」オブジェクト(WKInterfaceLabel)と「Image」オブジェクト(WKInterfaceImage)を一つづつ配置します。


「Label」オブジェクト(WKInterfaceLabel)と「Image」オブジェクト(WKInterfaceImage)をTableRowController.hのpropertyと接続します。

 

それぞれにTitleを付けます。


画像表示のカスタムクラスを作成します。

右クリックでFile 一覧を出し「 New File...」を選択します。

 

iOSの「Source」から「Cocoa Touch Class」を選択し「Next」をクリックします。


Class名は「DetailInterfaceController」にしSubclassは、「WKInterfaceController」を選択します。

 

DetailInterfaceController.h

DetailInterfaceController.m

が追加されます。


テーブル一覧と詳細表示画像の保存先
WatchKitTableApp01 WatchKit App/Images.xcassetsにドラックし保存します。


テーブル表示のソースコード

TableInterfaceController.mに記述します。

#import "TableInterfaceController.h"

#import "TableRowController.h"

#import "DetailInterfaceController.h"


@interface TableInterfaceController()


// 花火一覧テーブル

@property (weak, nonatomic) IBOutlet WKInterfaceTable *firetable;

@property (strong, nonatomic) NSArray *fireNames;

@property (strong, nonatomic) NSArray *fireimages;

@property (strong, nonatomic) NSArray *fireBigimages;

@end



@implementation TableInterfaceController


// 最初に呼び出されるメソッド

- (void)awakeWithContext:(id)context {

    [super awakeWithContext:context];

    

    // Configure interface objects here.

    

    // テーブルデータの読み込み

    [self loadTableData];

}


// ユーザーにUIが表示されたタイミングで呼び出されるメソッド

- (void)willActivate {

    // This method is called when watch view controller is about to be visible to user

    [super willActivate];

}


// UIが非表示になったタイミングで呼び出されるメソッド

- (void)didDeactivate {

    // This method is called when watch view controller is no longer visible

    [super didDeactivate];

}


// TableImageに画像、Labelにテキストを流し込む

- (void)loadTableData {

    

    // 花火名

    self.fireNames = @[@"千輪", @"菊先", @"菊先", @"菊先", @"型物"];

    // サムネイル画像小

    self.fireimages =  

         @[@"imgm01.png",@"imgm03.png",@"imgm04.png",@"imgm05.png",@"imgm06.png"];

    // 画像大

    self.fireBigimages =

         @[@"img01.png",@"img03.png",@"img04.png",@"img05.png",@"img06.png"];

    // 花火名 行の要素を設定

    [self.firetable setNumberOfRows:self.fireNames.count withRowType:@"default"];

    

    [self.fireNames enumerateObjectsUsingBlock:^(NSString *firName, NSUInteger idx, BOOL *stop) {

        

        // テーブル行の生成

        TableRowController *row = [self.firetable rowControllerAtIndex:idx];

        

        // テーブル行 花火名前に転送 (TableRowController)

        [row.firename setText:firName];

        // テーブル行 花火画像に転送 (TableRowController)

        [row.fireicon setImageNamed:[self.fireimages objectAtIndex:idx]];


    }];

}


// Tableをタップした時の画面遷移処理

- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex {

    

    // 画像名を指定して詳細表示

    [self presentControllerWithNames:@[@"DetailInterfaceController"]

                            contexts:@[[self.fireBigimages objectAtIndex:rowIndex]]];

}


@end


awakeWithContextに記述
iOSのviewDidLoadに該当する部分がWatchKitでは、awakeWithContextになります。ここにテーブルデータの読み込み部分を記載すれば起動時に動作します。

loadTableDataメソッドでは、テーブル一覧に表示したい花火名、サムネイル画像、Secondページにて表示する画像大など配列に記述しておきます。



enumerateObjectsUsingBlock ブロックメソッドについて
enumerateObjectsUsingBlockはNSArray.hで宣言されており、iOS4.0以降で利用できます。
配列の最初の要素から最後の要素まで反復して、配列内のオブジェクトを呼び出します。

enumerateObjectsUsingBlock:

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block

enumerateObjectsUsingBlockメソッドのブロックは3つの引数を取ります。
パラメータ
・obj : 配列内の要素
・idx : 配列内の要素のインデックス
・stop : ブール値への参照。反復処理を停止する場合、値にYESを代入します。
(stopはBOOL型のポインタな点に注意してください)


Blockパラメータがnilの場合、このメソッドは例外を発生させます。 
このメソッドは同期的に実行されます。


このブロックメソッドに記述するのが、テーブル行の表示になります。


        // テーブル行の生成

        TableRowController *row = [self.firetable rowControllerAtIndex:idx];

        

        // テーブル行 花火名前に転送 (TableRowController)

        [row.firename setText:firName];

        // テーブル行 花火画像に転送 (TableRowController)

        [row.fireicon setImageNamed:[self.fireimages objectAtIndex:idx]];



テーブル表示の花火一覧


Second画像表示 (詳細表示)

いまのままではサムネイルが並ぶだけなので、選択したら一画面で表示するようにします。 新規にWKInterfaceControllerクラスを作成し、名前はDetailInterfaceControllerとします。


Storyboard上にInterface Controller(View Controller)を配置します。


Custom ClassをDetailInterfaceControllerとして追加しておきます。

 

Imageを貼り付けます。

Imageは画面いっぱいに表示したいのでwidthもheightもRelative to Containerにします。



ImageとDetailInterfaceControllerにOutletを紐付けします。

@property (weak, nonatomic) IBOutlet WKInterfaceImage *image;


IdentiferをDetailInterfaceControllerとして追加しておきます。


TableInterfaceController.mに下記を追加します。行を選択した際にDetailInterfaceControllerを呼びつつ、表示画像名を渡します。


// 画像名を指定して詳細表示

[self presentControllerWithNames:@[@"DetailInterfaceController"]

                        contexts:@[[self.fireBigimages objectAtIndex:rowIndex]]];



DetailInterfaceControllerで、画像を表示します。

[self.image setImageNamed:context];


これで行選択すると詳細に飛ぶようになり、下記のように表示されます。

DetailInterfaceController 花火画像表示

 

DetailInterfaceController.mの記述。

#import "DetailInterfaceController.h"



@interface DetailInterfaceController()


// 画像

@property (weak, nonatomic) IBOutlet WKInterfaceImage *image;


@end



@implementation DetailInterfaceController


// 最初に呼び出されるメソッド

- (void)awakeWithContext:(id)context {

    [super awakeWithContext:context];

    

    // Configure interface objects here.

    

    // 画像を表示

    [self.image setImageNamed:context];

}


// ユーザーにUIが表示されたタイミングで呼び出されるメソッド

- (void)willActivate {

    // This method is called when watch view controller is about to be visible to user

    [super willActivate];

}


// UIが非表示になったタイミングで呼び出されるメソッド

- (void)didDeactivate {

    // This method is called when watch view controller is no longer visible

    [super didDeactivate];

}


@end


花火一覧(Fire List)

 

GitHub WatchKitTableApp01

  

目 次