2014年1月21日火曜日

[iOS][Objective-C]UITableViewについて


どうも。

いろんなiOSアプリがあると思いますが、
高確率で出くわさなきゃいけないコンポーネントが、
UITableView。

設定画面のような、
項目の一覧としての存在だったり、
検索結果の一覧のような存在だったり。

基本的かつ使用頻度が高い割に、
サンプル画面ひとつ作るのにも、
それなりの手間がかかったり…。

TableViewの各行の内容たる、
UITableViewCellというのも、
それなりのクセがあって面倒…。

ボタンやラベルを好きな位置に配置して、
とりあえずRunすれば、
「ラベルとボタンが表示されたよ☆」
というのとはワケが違う(´・ω・`)

最低限、
・セクション数
・各セクション内の行数
・各行に表示する内容
といった、
TableViewの構成要素を、
デリゲートメソッドやら何やら、
オーバーライドして書かなきゃいけない。

上記だけでも、
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
と、
見るだけでめまいが…

しかも、
TableViewを使う側からは、
どれも(感覚的に見れば)静的に設定している。

よくあるサンプルプログラムなら、
ベタ打ちの値でぶち込んで、
「とりあえず表示されてよかったね☆」
と、ちゃんちゃん(`・ω・´)

でいいかも知れませんが、
実際の開発では、
「表示される行数は可変です( *`ω´)」
ということがほとんど。
更に、
非同期でサーバからデータが送られてきたり…。

行き着く答えは、
表示の処理と表示データを切り離して、
NSMutableArrayの様なコレクションクラスで、
表示データをハンドリングするということ。

非同期でレスポンスがあったとして、
・Arrayの内容を更新
・TableViewをリロード(reloadData)

とすることで、
デリゲートメソッドが再び走るので、
行数だの内容だのがリフレッシュされる。

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
では、
[xxArray count]
で行数を返すようにしてやればいいし、

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
では、
[xxArray objectAtIndex:indexPath.row]
で内容を取り出してやればいい。

と、
ベタ打ちの値を出すにしても、
Arrayにぶち込んで、
それをハンドリングするようなクセをつけておいた方がよさそう。

よくあることとして、
まずは固定値でいいから画面イメージというか、
モックアップのようなものを作って、
fixしたらそれをベースに実際のものを作る。
といったような流れ。

この時に、
ベタベタと書くのではなく、
ある程度最終形を見据えておいて、
ベタ打ちだけど、
Arrayでハンドリングされている形だと、
後々のコーディングが非常に楽(`・ω・´)

他にもっとスマートな方法ってあんのかな?


それでは。
ちゃお☆


まこぴー。