悩み
UITableView
を使っているとき、小手先のDelegate実装やらUITableViewControllerなどのおかげで、
いつも以下のようなことを考えもやもやしていた。
-
UITableViewDataSource
の実装をしたいのであって、UITableView
やUITableViewController
を触りたいわけじゃない。 - そして
UITableViewDataSource
のコードしか実質書いてない。 - 分割したい
- これはおかしい。あるべきものはあるべきところへ収まらなければならない。
- 分割したい分割したい分割したい
- せっかく
UITableViewDataSource
をUIViewController
から分離したのに、結局init
でdataSource
のためにインスタンスを生成するだけのUIViewController
カスタムクラスを書いている。 - こんな無駄なクラスは抹消しなくてはならない。
- 削除したい削除したい削除したい
ということでStoryboardできちんとOutletを貼って、必要十分なクラスでTableViewを使いましょう。
手順
プロジェクトの作成
- シングルビュープロジェクトを作成する
TableViewを配置する
-
Main.storyboard
を開き、デフォルトで存在するViewController
にTableView
を配置する
TableViewCellを配置する
-
TableView
にTableViewCell
を追加する。 - cellの
Identifier
にはcell
をセットする
UITableViewDataSourceを実装する
-
UITableViewDataSource
を実装したNSObject
のカスタムクラスを作成する
例として、8時、9時、10時をそれぞれ15分刻みにセルで出力する。
import UIKit
class DataSource: NSObject, UITableViewDataSource {
let sections = [8, 9, 10]
let rows = [0, 15, 30, 45]
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let hour = sections[section]
return String(format: "%02d:00〜", hour)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rows.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
let hour = sections[indexPath.section]
let minute = rows[indexPath.row]
cell.textLabel?.text = String(format: "%02d:%02d", hour, minute)
return cell
}
}
StoryboardにDataSourceを追加する
Object
をViewController
に追加する
そして、Object
のカスタムクラスにDataSource
を指定する。
TableViewとDataSourceを繋ぐ
TableView
を右クリックしてメニューを開き、dataSource
のOutletをDataSource
オブジェクトを繋ぐ。
実行する
ビルドして動作が確認できれば完成。
UITableView
のカスタムクラスなんていらなかったのだ。
UITableViewDelegete
も同じ要領で実装できる。