メニュー画面などのUITableView をViewController 内でちまちまと定義するのはコードが分散するわ見辛いわで泣けてきます。
で、plist でUITableView の構造を定義しておいて、それを逐次展開すればコードがスッキリするので、やってみました。
手順
1.plistファイルを作成
2.plist ファイルを展開して、UITableView を描画
以上!
清々しいまでのシンプルさ。
1.plist ファイルを作成
TableStructures.plist
plistファイルはNew File…から追加します。
iOS のResource でProperty List を追加すればOKです。
plist は結局XMLファイルなので、中身はこんな感じ。
作成したplist をOpen As … からSource Code で見ると中身を見ることが可能です。
TableStructures.plist
Table Title セクション1 Rows Identifier CellType1 Title セル1-1 SubTitle サブタイトル1-1 Segue Segue1-1 Identifier CellType1 Title セル1-2 SubTitle サブタイトル1-2 Segue Segue1-2 Identifier CellType2 Title セル1-3 SubTitle Segue Title セクション2 Rows Identifier CellType1 Title セル2-1 SubTitle サブタイトル2-1 Segue Segue2-1 Identifier CellType2 Title セル2-2 SubTitle Segue Identifier CellType2 Title セル2-3 SubTitle Segue
2.plist ファイルを展開して、UITableView を描画
plist ファイルを展開して、UITableView を描画します。
テーブルを定義する構造はすべてplistから取得するので、テーブルを描画するコードはかなりスッキリします。
SampleViewController.h
ViewController.h のインスタンス変数にテーブル構造を格納する配列を設置します。
NSArray* tableStructure_;
SampleViewController.m
ViewController.m の各テーブル描画メソッド内でテーブル構造を展開して利用します。
// 前略 - (void)viewDidLoad { [super viewDidLoad]; // plist ファイルを展開して、ヘッダーファイルのインスタンス変数tableStructure_ に格納 NSString* filePath = [[NSBundle mainBundle] pathForResource:@"TableStructures" ofType:@"plist"]; NSDictionary* dic = [NSDictionary dictionaryWithContentsOfFile:filePath]; tableStructure_ = [NSArray arrayWithArray:[dic objectForKey:@"Table"]]; } // セクション数 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [tableStructure_ count]; } // セクションヘッダーのタイトル - (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return [[tableStructure_ objectAtIndex:section] objectForKey:@"Title"]; } // セクションごと行数 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [[[tableStructure_ objectAtIndex:section] objectForKey:@"Rows"] count]; } // 各セル - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // セクション定義取得 NSDictionary* dicSection = [tableStructure_ objectAtIndex:indexPath.section]; // 行配列定義取得 NSArray* rows = [dicSection objectForKey:@"Rows"]; // セル定義取得 NSDictionary* dicCell = [rows objectAtIndex:indexPath.row]; // セル識別子取得 NSString* cellIdentifier = [dicCell objectForKey:@"Identifier"]; // セル取得 UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; // セル識別子によりアクセサリを追加 if ( [cellIdentifier isEqualToString:@"CellType2"] ) { UISwitch* boolSwitch = [[UISwitch alloc] initWithFrame:CGRectZero]; [boolSwitch addTarget:self action:@selector(changeSwitchValue:) forControlEvents:UIControlEventValueChanged]; cell.accessoryView = boolSwitch; } // セルタイトル取得・設定 NSString* cellTitle = [dicCell objectForKey:@"Title"]; [cell.textLabel setText:cellTitle]; // セルサブタイトル取得・設定 NSString* cellSubTitle = [dicCell objectForKey:@"SubTitle"]; [cell.detailTextLabel setText:cellSubTitle]; return cell; } // セル選択 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // セクション定義取得 NSDictionary* dicSection = [tableStructure_ objectAtIndex:indexPath.section]; // 行配列定義取得 NSArray* rows = [dicSection objectForKey:@"Rows"]; // セル定義取得 NSDictionary* dicCell = [rows objectAtIndex:indexPath.row]; // セグエ識別子取得 NSString* segueIdentifier = [dicCell objectForKey:@"Segue"]; // セグエ識別子があればセグエ呼び出し if ( ![segueIdentifier isEqualToString:@""] ) { [self performSegueWithIdentifier:segueIdentifier sender:self]; } } // 以下略
不明な箇所や、そここうやった方が良いんでね?などありましたら、コメント頂けると嬉しいです。
普通にできません。
cellInfoが未定義でランさえさせてもらえない状況です
>ano さん
ああ!ごめんなさい。
cellInfo になっていますが、objectForKey: でタイトルやサブタイトルを引っ張っているんだから、dicCell ですね。
私の誤記です。
訂正しておきました。
ご容赦を。