テーブル(2)

2010. 05. 03
サンプルコードの説明に入る前に、TableViewに必要な2つのプロトコルについて、リファレンスの概要をお話しします。


●UITableViewDataSourceプロトコル

UITableViewDataSourceプロトコルは、アプリケーションのデータモデルをUITableViewオブジェクトとして取り扱うために採用します。

データソースは、テーブルビューを構築・変更するのに必要なテーブルビューオブジェクトの情報を提供します。

データモデルの典型的な役割は、テーブルビューの外観を構築する最小限の情報をデータソースから与えることです。

テーブルビューオブジェクトのデリゲートは、UITableViewDelegateプロトコルを採用したオブジェクトで、テーブルビューを構築する情報を提供します。

プロトコルの必要なメソッドは、テーブルビューを表示するのに必要な、UITableViewオブジェクトのセクション数とセクション毎の行数の情報を提供します。

データソースは実行するメソッドのオプションによって、色々なテーブルビューの外観の構成や、行の挿入、削除、並べ替えを行います。

注:テーブルビューでスワイプして削除できるようにする(デリートボタンを表示し、行を水平に横切って操作する)には、tableView:commitEditingStyle:forRowAtIndexPath:メソッドを実行する必要があります。

多くのメソッドはNSIndexPathオブジェクトを引数とします。

UITableViewは、NSIndexPathで表現された行インデックス(rowプロパティ)とセクションインデックス(セクションプロパティ)、そして指定した行インデックスとセクションインデックス(indexPathForRow:inSection:クラスメソッド)から組み立てたインデックスパスを宣言します。

(各インデックスパスの最初のインデックスは、セクションと次の行の識別をします)


●UITableViewDelegateプロトコル

UITableViewオブジェクトのデリゲートはUITableViewDelegateプロトコルを採用する必要があります。

プロトコルのオプションメソッドは、デリゲートによる選択の管理、セクションのヘッダとフッタの設計、セルの削除や並べ替えの補助などを行います。

多くのUITableViewDelegateメソッドは、NSIndexPathオブジェクトを引数または変数とします。

UITableViewは、NSIndexPathで表現された行インデックス(rowプロパティ)とセクションインデックス(セクションプロパティ)、そして指定した行インデックスとセクションインデックス(indexPathForRow:inSection:クラスメソッド)から組み立てたインデックスパスを宣言します。 

セクション内の行の位置は、通常行のインデックス番号を求める前に、セクションインデックス番号を求める必要があります。


●チュートリアル:テーブルを使ったアプリケーション

iPhone SDKプログラミング大全』の『チュートリアル:テーブルを使ったアプリケーション』について説明します。

本文では『チュートリアル形式で説明していく』とあるのはいいのですが、どういう物を作るのかという最終形態の説明も無く、そのままプロジェクトの作成から入るので先に説明します。

235

今回はプレーンスタイルのテーブルビューで、namesという一次配列をデータソースとしています。

セクションは1つ、ヘッダ/フッタ、インデックスなどが無いシンプルなものです。


●プロジェクトの作成

Window-based Applicationテンプレートで、『Table』というプロジェクト名で作成します。

236


●TableAppDelegate.hの編集

TableAppDelegate.hを開き、UITableViewDataSourceプロトコルとデータソースとなるnames配列の宣言を追加します。
(太字が追記した部分)

@interface TableAppDelegate : NSObject <UIApplicationDelegate, UITableViewDataSource> {
    NSArray *names;
    UIWindow *window;
}

237

本文中に説明がありませんが、『テーブル(1)』の『UITableViewの概要』で説明しているように、データソースは、UITableViewDataSourceプロトコルと、UITableViewDelegateプロトコルのデリゲートを採用している必要があります。

しかし、サンプルではUITableViewDataSourceプロトコルは追加していますが、UITableViewDelegateプロトコルを追加していません。

それでもコンパイルエラーが出ないのは、UITableViewDelegateプロトコルに必須メソッドが無く(UITableViewDataSourceプロトコルには必須メソッドがある)、セル選択時に応答する部分を実装していないからだと思われます。

まともにTableViewを実装する際には、UITableViewDelegateプロトコルの実装を忘れないようにしましょう。
(UITableViewDelegateプロトコルのメソッドを使おうとすれば、コンパイルエラーが出るとは思いますが・・・)


●ユーザインターフェイスのレイアウト

p.155の冒頭で『MainMenu.xibを開く』とありますが、MainWindow.xibの間違いです。

Table Viewオブジェクトを画面いっぱいに貼付けます。

238


●データソースの接続

貼付けたTable Viewオブジェクトを右クリックしてConnections Panelを開き、OutletsのdataSourceをDocument WindowのTable App Delegateに接続します。

239


●TableAppDelegate.mの編集

p.157でTestAppDelegate.mとありますが、TableAppDelegate.mの間違いです。

データソースとなるnames配列の初期化と、メソッドの追加を行います。
(太字が追記した部分)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch
    // namesを初期化
    names = [[NSArray arrayWithObjects:@"ゆきぽ", @"あふぅ", @"ちひゃー", nil] retain];

    [window makeKeyAndVisible];

    return YES;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // namesの数を返す
    return [names count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // セルを作る
    UITableViewCell *cell;
    cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewStyleDefault reuseIdentifier:@"UITableViewCell"];
        [cell autorelease];
    }

    // セルにテキストを設定
    cell.textLabel.text = [names objectAtIndex:indexPath.row];

    return cell;
}

アプリケーションのライフサイクル(2)』で説明しているように、現在はapplicationDidFinishLaunching:メソッドの代わりにapplication:didFinishLaunchingWithOptions:メソッドを使っています。

後述しますが、iPhone OS 3.0以降ではinitWithFrame:reuseIdentifier:メソッドの代わりにinitWithStyle:reuseIdentifier:を使うように推奨されていますので、入れ替えています。

また、サンプルコードをそのまま入力すると、最後の方の『セルにテキストを設定』のコードでコンパイルエラー('setText:' is deprecated)が出ます。

240

これは、『cell.text』の部分を『cell.textLabel.text』と修正すると治ります。
(iPhone OS 3.0で、textプロパティが廃止され、textLabelに置換されたためです)

さて『TableAppDelegate.hの編集』で、UITableViewDataSourceプロトコルには必須メソッドがあると説明しましたが、それがtableView:numberOfRowsInSection:とtableView:cellForRowAtIndexPath:です。

tableView:numberOfRowsInSection:は、テーブルビューを構成するのにあたって、そのセクションに何行あるかを指定します。

tableView:cellForRowAtIndexPath:は、セルの内容を構築します。


・tableView:numberOfRowsInSection:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

指定したテーブルビューのセクションの行番号を返します(必須)

tableView:構築するテーブルビューオブジェクトを指定します

section:tableView内のセクションのインデックス番号を指定します


・tableView:cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

指定したテーブルビューの特定の場所に挿入する、セルのデータソースを指定します(必須)

戻り値はUITableViewCellを継承したオブジェクトで、テーブルビューの行として使うことができます

(上手く訳せなかったので原文を載せます)An assertion is raised if you return nil.

戻り値のUITableViewCellオブジェクトは、パフォーマンス上の理由からアプリケーションでしばしば再利用されます

そのため、セルオブジェクトを構築する際に、予めテーブルビューにdequeueReusableCellWithIdentifier:メッセージを送り、再利用することを明示しておきます。

再利用可能なセルオブジェクトとなる識別子は、UITableViewCellのinitWithFrame:reuseIdentifier:メソッドを呼び出して、デリゲートがセルオブジェクトを初期化する時に割り当てます。

アクセサリビューや編集コントロールなど、テーブルセルの様々な属性は、セルのセパレータやデータソースの提供する情報に基づいて自動的に設定されます

tableView:セルのテーブルビューオブジェクトを指定します

indexPath:tableView内の行の位置のインデックスパスを指定します


・dequeueReusableCellWithIdentifier:

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier

識別子の位置で示された、再利用可能なテーブルビューのセルオブジェクトを返します

戻り値は、識別子で関連付けられたUITableViewCellオブジェクトで、再利用可能なセルオブジェクトが無い場合はnilを返します

パフォーマンス上の理由で、テーブルビューのデータソースは一般的にUITableViewCellオブジェクトを再利用するもので、tableView:cellForRowAtIndexPath:メソッドの中で行にセルを割り当てる時に指定します

テーブルビューは、UITableViewCellオブジェクトの列またはリストを保持し、テーブルビューのデリゲートは再利用のマークを維持します

(UITableViewCellのinitWithFrame:reuseIdentifier:メソッドで)生成時に再利用の識別子を割り当てることで、再利用のセルのマーキングを行います

データソースはdequeueReusableCellWithIdentifier:メソッドを実行し、この列内の特定の『テンプレート』セルオブジェクトにアクセスできます

セルの再利用識別子は、reuseIdentifierプロパティによってUITableViewCellを明示します

identifier:再利用可能なセルオブジェクトの、識別子の文字列を指定します
デフォルトの識別子はクラス名ですが、任意の値を設定することもできます


・initWithFrame:reuseIdentifier:

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier

テーブルセルオブジェクトを初期化して返します
(iPhone OS 3.0では非推奨。代わりにinitWithStyle:reuseIdentifier:を使用してください)

戻り値は、初期化したUITableViewCellオブジェクト、またはオブジェクトが生成できなかった場合はnilを返します

このメソッドはクラスの指定する初期化メソッドです

再利用識別子はテーブルビューのセル(行)関連付けされ、一般的な構成と同じくセルの内容は含まれていません

tableView:cellForRowAtIndexPath:の実装の中で、テーブルビューのデリゲートはUITableViewメソッドのdequeueReusableCellWithIdentifier:メソッドを呼び出し、再利用識別子を渡して、セルオブジェクトを取得して現在の行の基礎として使います

frame:セルの枠の矩形を指定します
テーブルビューは自動的にセルの位置と最適なサイズを生成しますので、ほとんどの場合CGRectZeroを渡します
ただし、もし複数のサブビューを持つカスタムセルの場合、それぞれ独自に自動サイズ調整マスクを用いる時は、non-zero枠の矩形を指定すれば、テーブルビューはサブビューの位置とセルのサイズを自動的に調整します

reuseIdentifier:テーブルビューで複数の行を描く際に、セルオブジェクトを再利用するための識別子の文字列を指定します
再利用するセルオブジェクトが無い場合はnilを渡します


・initWithStyle:reuseIdentifier:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier

スタイルと再利用識別子を指定してテーブルセルを初期化して返します

戻り値は、初期化したUITableViewCellオブジェクト、またはオブジェクトが生成できなかった場合はnilを返します

このメソッドはクラスの指定する初期化メソッドです

再利用識別子はテーブルビューのセル(行)関連付けされ、一般的な構成と同じくセルの内容は含まれていません

tableView:cellForRowAtIndexPath:の実装の中で、テーブルビューのデリゲートはUITableViewメソッドのdequeueReusableCellWithIdentifier:メソッドを呼び出し、再利用識別子を渡して、セルオブジェクトを取得して現在の行の基礎として使います

UITableViewCellのスタイルと異なる特徴を持つテーブルセルを構成する場合は、カスタムセルを作る必要があります

個々のセルの行の高さを設定したい場合は、デリゲートメソッドのtableView:heightForRowAtIndexPath:を実装してください

style:セルのスタイルの定数を指定します
(セルスタイルを参照してください)

reuseIdentifier:テーブルビューで複数の行を描く際に、セルオブジェクトを再利用するための識別子の文字列を指定します
再利用するセルオブジェクトが無い場合はnilを渡します
同じフォームの全てのセルには、同じ再利用識別子を使用してください


・セルスタイル(Cell Style)

セルのスタイルには4種類有り、UITableViewCell.hで定義されています。

全てのセルスタイルにおいて、テキストラベルの拡大はtextLabelプロパティ、縮小はdetailTextLabelプロパティによって利用できます。

typedef enum {
    UITableViewCellStyleDefault,
    UITableViewCellStyleValue1,
    UITableViewCellStyleValue2,
    UITableViewCellStyleSubtitle
} UITableViewCellStyle;

・UITableViewCellStyleDefault

セルの単純なスタイルで、テキストラベル(左寄せ黒文字)とオプションで画像を表示できます。

・UITableViewCellStyleValue1

ラベルをセルの左側に左寄せ黒文字で、右側にサブラベルを小さな右寄せ青文字で表示します。
(環境設定アプリケーションで使われています)

・UITableViewCellStyleValue2

左端から少し離れた位置に、ラベルを右寄せ青文字で、サブラベルを小さな左寄せ黒文字で表示します。
(電話や連絡先アプリケーションで使われています)

・UITableViewCellStyleSubtitle

ラベルを左側に左寄せ黒文字で、その下にサブラベルを小さな灰色文字で表示します。
(iPodアプリケーションで使われています)

詳細は『iOS Table Viewプログラミングガイド』の『Table View Cellの標準スタイル』を参照してください


●ビルドと実行

結果は下図のようになります。

235

セルを選択することはできますが、特に応答するようなメソッドを記述していませんので、選択されているという表示になるだけです。



参考文献

UITableView Class Reference

UITableViewDataSource Protocol Reference

UITableViewDelegate Protocol Reference

UITableViewCell Class Reference

iOS Table Viewプログラミングガイド

iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)iPhone SDK 3 プログラミング大全 実践プログラミング (MacPeople Books)
(2009/09/08)
木下 誠

商品詳細を見る






SoundSport Pulse wireless headphones
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
04 | 2017/05 | 06
Sun Mon Tue Wed Thu Fri Sat
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

SoundSport Pulse wireless headphones
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR