2014年9月16日火曜日

UITableViewのセルの高さを動的に計算するSelf-Sizing Cellsを試してみた(iOS8, Swift)

はじめに
UITableviewCellの高さを動的に変更する実装はiOS7の頃(?)から可能で、iOS8では実装が簡略されてさらにパフォーマンスが高いよといったお話です。
どういう点が簡略化されたの?
iOS7では主に以下の実装が必要でした。
  1. AutoLayoutを有効にしてConstraintsを設定
  2. tableView:heightForRowAtIndexPath: メソッド実装によるセルの高さ計算
  3. tableView:cellForRowAtIndexPath: メソッド実装
iOS8の場合、 2番目の高さを計算する処理がまるっと省略可能で、おまじない程度の設定で済みます。
Constraintsの追加と設定(AutoLayout)
本例ではUITableViewControllerとして実装されたUITableVivew及びUITableViewCellのContentViewにLabelを一つ配置しています。 まずはLabelのConstraintsを追加していきます。

まずはUITableviewControllerの配置。
Cell上へラベルの配置。
Cell上のContentViewにLabelを一つ配置しています。
Constraintsを追加していきます。Labelの上下左右のマージンを設定します。
ラベルは複数行を許可するためLinesの値を0に設定しておく必要があります。
全体的な構成はこんな感じ。
UITableViewCellは独自のカスタムクラスを設定しておき、ラベルのアウトレットの作成をしておきます。
rowHeightの設定
tableViewのプロパティであるrowHeight及びestimatedRowHeightの設定を行います。 以下、UITableViewControllerの実装クラスです。
  1. class TableViewController : UITableViewController {
  2. override func viewDidLoad() {
  3. //
  4. super.viewDidLoad()
  5. //initialize
  6. tableView.estimatedRowHeight = 60
  7. tableView.rowHeight = UITableViewAutomaticDimension
  8. }
  9. //MARK: implementation of uitableviewcontroller datasources
  10. override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
  11. return 1
  12. }
  13. override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  14. return 5
  15. }
  16. override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  17. //
  18. let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as CustomCell
  19. //dummy text
  20. var dummyString = "01234567890"
  21. for i in 0...indexPath.row {
  22. dummyString += dummyString
  23. }
  24. //set text
  25. cell.customLabel.text = "index : \(indexPath.row), dummyString : \(dummyString)"
  26.  
  27. return cell
  28. }
  29. }
おまじないはviewDidLoadメソッド内で実装している以下の箇所
tableView.estimatedRowHeight = 60
tableView.rowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
の設定が自動設定を表しています。estimateRowHeightは設定することでスクロール中のパフォーマンス向上につながるらしいです。
tableView:cellForRowAtIndexPath: メソッド実装
rowが増すごとに表示文字列を増やしているダミー処理がありますが、特に通常と変わった実装はありません。
  1. override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  2. //
  3. let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as CustomCell
  4. //dummy text
  5. var dummyString = "01234567890"
  6. for i in 0...indexPath.row {
  7. dummyString += dummyString
  8. }
  9. //set text
  10. cell.customLabel.text = "index : \(indexPath.row), dummyString : \(dummyString)"
  11.  
  12. return cell
  13. }
実装結果
実行イメージ。
もし、tableView.rowHeight = UITableViewAutomaticDimension の設定を行わないと以下のようになります。
コードの詳細はGitHubを参照して下さい。
https://github.com/takuran/SelfSizingCellExample
参考:What's New in Table and Collection Views(https://developer.apple.com/videos/wwdc/2014/)
※上記参考先リンクはiOS Developer 登録していないと参照出来ないかも。スミマセン。

0 件のコメント :

コメントを投稿