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の実装クラスです。
class TableViewController : UITableViewController {
    
    override func viewDidLoad() {
        //
        super.viewDidLoad()
        
        //initialize
        tableView.estimatedRowHeight = 60
        tableView.rowHeight = UITableViewAutomaticDimension
        
    }
    
    //MARK: implementation of uitableviewcontroller datasources
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as CustomCell
        
        //dummy text
        var dummyString = "01234567890"
        for i in 0...indexPath.row {
            dummyString += dummyString
        }
        //set text
        cell.customLabel.text = "index : \(indexPath.row), dummyString : \(dummyString)"

        return cell
    }
}
おまじないはviewDidLoadメソッド内で実装している以下の箇所
tableView.estimatedRowHeight = 60
tableView.rowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
の設定が自動設定を表しています。estimateRowHeightは設定することでスクロール中のパフォーマンス向上につながるらしいです。
tableView:cellForRowAtIndexPath: メソッド実装
rowが増すごとに表示文字列を増やしているダミー処理がありますが、特に通常と変わった実装はありません。
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as CustomCell
        
        //dummy text
        var dummyString = "01234567890"
        for i in 0...indexPath.row {
            dummyString += dummyString
        }
        //set text
        cell.customLabel.text = "index : \(indexPath.row), dummyString : \(dummyString)"

        return cell
    }
実装結果
実行イメージ。
もし、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 件のコメント :

コメントを投稿