UITableView!
今回はiPhoneの中でもよく使われるであろうUITableViewを使用してみたいと思います。
TableViewを使う際にはUITableViewとUITableViewControllerの二つの選択肢があるのですが
今回はUITableViewControllerを使用します。
UITableViewControllerはUITableViewよりも自動的にいろいろやってくれます。
例えばこんなこと。
- テーブルが表示される際(viewWillAppear:)に、データのリロード、選択行の解除。
- テーブルが表示された後(viewDidAppear:)に、スクロールバーの点滅。
- ナビゲーションバーの編集/完了ボタンを押したときに編集/通常モードに移行。
こんなアプリが出来上がるはずですね。
さて今回もTableDemoという名前で「Windows-Based Application」で作成します。
そこでできたプロジェクト内のフォルダ「Classes」を選択し
「ファイル」→「新規ファイル」→「UIviewController subClass」を選択、TableDemoViewControllerと名前を付けて保存します。
いつも通り、Interface Builderは切ってくださいね。
では、いつもどおり、ViewControllerから始めます。
でも、本の通り打ち込んだ感じでソースを読んでも少し分からないとこもあります。。。
iPhone SDK Application Development: Building Applications for the AppStore
- 作者: Jonathan Zdziarski
- 出版社/メーカー: O'Reilly Media
- 発売日: 2009/02/06
- メディア: ペーパーバック
- 購入: 2人 クリック: 110回
- この商品を含むブログ (14件) を見る
TableDemoViewController.h
#import <UIKit/UIKit.h> // TableViewを使うのでUIViewContorollerを使うのではなく、UITableViewControllerを使う @interface TableDemoViewController : UITableViewController { // NSMUtableArrayはインスタンス作成後、可変なサイズの配列 // 可変じゃないのはNSArray NSMutableArray *fileList; } -(void) startEditing; -(void) stopEditing; -(void) reload; @end
TableDemoViewController.m
#import "TableDemoViewController.h" @implementation TableDemoViewController -(id) init{ self = [super init]; if(self != nil){ [self reload]; // navigation Barの右側に[Edit]ボタンを表示する。 self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(startEditing)] autorelease]; // navigation Barの左側に[reload]ボタンを表示する。 self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"reload" style:UIBarButtonItemStylePlain target:self action:@selector(reload)] autorelease]; } return self; } -(void)startEditing{ // 編集モードにする [self.tableView setEditing:YES animated:YES]; // navigation Barの右側に[Done]ボタンを表示する。 self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(stopEditing)] autorelease]; } -(void)stopEditing{ // 編集モードをやめる [self.tableView setEditing:NO animated:YES]; // navigation Barの右側に[Edit]ボタンを表示する。 self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(startEditing)] autorelease]; } -(void) reload{ // NSDirectoryEnumeratorはディレクトリ内のファイル名を取り出せるようにする NSDirectoryEnumerator *dirEnum; NSString *file; fileList = [[NSMutableArray alloc] init]; // homeディレクトリ内のファイル名を格納する dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:NSHomeDirectory()]; // ファイル名を次々に取り出す while((file = [dirEnum nextObject])){ [fileList addObject:file]; } [self.tableView reloadData]; } // numberOfSectionsInTableViewはテーブル内のセクション数を返す。今回は1個 -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } // numberOfRowsInSectionはセクション内の行数を返す。 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return [fileList count]; } // cellForRowAtIndexPathはセルの中身を表示する(ここが少し理解があやふや。。。) -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ // fileListの1行目を表示する? NSString *CellIdentifier = [fileList objectAtIndex:[indexPath indexAtPosition:1]]; // セルを作成する UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // 以前つかったcellのデータがあるのか if(cell == nil){ // 無ければ作成する cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; cell.text = CellIdentifier; UIFont *font = [UIFont fontWithName:@"Courier" size:12.0]; cell.font = font; } return cell; } // commitEditingStyleはEdit呼ばれた時に削除モードになるように呼ばれるメソッドっぽい? -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle) editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ if(editingStyle == UITableViewCellEditingStyleDelete){ UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; for(int i=0; i < [fileList count]; i++){ if([cell.text isEqualToString:[fileList objectAtIndex:i]]){ [fileList removeObjectAtIndex:i]; } } NSMutableArray *array = [[NSMutableArray alloc] init]; [array addObject:indexPath]; [self.tableView deleteRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationTop]; } } // didSelectRowAtIndexPathはセルがタップされたらコールされる -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; // セルがタップされたらAlertの画面を出す UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"File Selected" message:[NSString stringWithFormat:@"You selected the File '%@'", cell.text] delegate:nil cancelButtonTitle:nil otherButtonTitles: @"OK", nil]; [ alert show]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return YES; } - (void)loadView { [super loadView]; } - (void)dealloc { [fileList release]; [super dealloc]; } @end
コメントを書いておきました。
cellForRowAtIndexPathとcommitEditingStyleが少しあやふや。。。
もう少し調べてみたいと思います。。。。
Delegateのソースは、今までと同様ViewControllerをインスタンス化してwindowにsubviewとして貼付けてるだけです。
TableDemoAppDelegate.h
#import <UIKit/UIKit.h> @class TableDemoViewController; @interface TableDemoAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; TableDemoViewController *viewController; UINavigationController *navigationController; } @property (nonatomic, retain) IBOutlet UIWindow *window; @property (nonatomic, retain) IBOutlet TableDemoViewController *viewController; @end
TableDemoAppDelegate.m
#import "TableDemoAppDelegate.h" #import "TableDemoViewController.h" @implementation TableDemoAppDelegate @synthesize window; @synthesize viewController; - (void)applicationDidFinishLaunching:(UIApplication *)application { window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; viewController = [[TableDemoViewController alloc] init]; navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; [window addSubview:[navigationController view]]; // Override point for customization after application launch [window makeKeyAndVisible]; } - (void)dealloc { [window release]; [super dealloc]; } @end
テーブルで一気に準備しておかなきゃならないメソッドが増えました。。。
もちょっと理解は深めたいな〜