メニュー画面などの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 ですね。
私の誤記です。
訂正しておきました。
ご容赦を。