LoginSignup
69
65

More than 5 years have passed since last update.

Autolayoutを使ったUITableViewCellの高さ計算を「手動」で行う実装

Last updated at Posted at 2015-06-28

iOS8からのTableViewCellの高さ自動計算は、上スクロールした時にはうまく動かない件で、UITableViewCellの高さ自動計算でハマる場合がある事がわかりました。
これを回避するには、estimatedHeightを使わずに、真面目に高さ計算を行えば良いです。

Autolayoutが無い時代には、これをごりごりと計算していたのですが、UITableViewCellにAutolayoutを使う事で、かなり簡略化できたのでその記録を残します。

おおまかな流れ

  • UITableViewDataSourceから参照できる所に、「表示する事の無い、高さ計算用のダミーセル」を用意します。
  • tableView:heightForRowAtIndexPath: で、ダミーセルを使って高さ計算を行います。
    • このときAutolayoutで計算ができるので、比較的楽です。

ソース

Objective-c
- (void)viewDidLoad {
    [super viewDidLoad];
...    
    // estimatedRowHeightはガタガタの原因になるので使わない。
//    self.tableView.estimatedRowHeight = 100;
//    self.tableView.rowHeight = UITableViewAutomaticDimension;

    // セルの高さを計算する用の、表示されないダミーのセルを用意する。
    // ここでdequeueするのは、実際に表示するセルを使います。
    self.dummyCell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell"];

}


/**
 Autolayoutを使ったUITableViewCellの高さ計算
 */
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 高さ計算用のダミーのセルに、cellForRowAtIndexPathで行うのと
    // 同じ設定をする。
    [self setupCell:self.dummyCell atIndexPath:indexPath];

    // 以下、サイズ計算用の処理です。
    // ダミーセルそのものに操作しても、サイズ計算は行われないので、
    // その内側にあるcontentViewに対して操作を行います。
    // contentViewを再レイアウトする
    [self.dummyCell.contentView setNeedsLayout];
    [self.dummyCell.contentView layoutIfNeeded];
    // contentViewの、Autolayoutに従った時のサイズを取得する
    CGSize size = [self.dummyCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    // UITableViewの高さは、contentViewと「区切り線」を含んだ高さなので、
    // 高さに区切り線分の高さを+1して返す
    return size.height+1;
}

/** MyTableViewCellの設定処理 */
// MyTableViewCellへの設定処理が重たい場合は、
// 「高さ計算で必要な設定」と「高さ計算では不要な設定」に
// 分けたほうが良いかもしれません。
-(void)setupCell:(MyTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger num = (NSUInteger)[self.array[indexPath.row] integerValue];
    cell.title.text = [self stringByLineNumber:num];
    cell.backgroundColor = [self colorByNumber:num];
}

/** 実際に表示するCellを返す */
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog( @"cellForRowAtIndexPath: row=%@",@(indexPath.row));
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"
                                                            forIndexPath:indexPath];
    [self setupCell:cell atIndexPath:indexPath];
    NSLog( @"cell=%@",cell);
    return cell;
}

ソース https://github.com/taktamur/iOS8CellHeight/tree/after

おわりに

iOS8からUITableViewCellの高さ計算が自動になって、やぁ便利になったなぁと思いましたが、使い方によっては思った動作にならないようです。
ただ自動計算せずとも、heightForRowAtIndexPathの中で、「Autolayoutを使った高さ計算」ができれば、少しの手間で「高さの手動計算」ができるようです。
なので、高さの自動計算は、場面に応じての使い分けになるのでしょうね。

69
65
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
69
65