本项目很多页面需要动态设置UITableView的cell的高度,在cell中内容比较简单时,比如cell只有一个UILabel,可以用boundingRectWithSize这样的方法直接计算UILabel的高度,但当cell结构比较复杂时就比较困难了。
网上看到一些办法,有人提出了如下方案:
1、在table的cellForRowAtIndexPath中,得到cell的同时设置cell的高度,比如:
//设置cell高度
CGRect cellFrame = [cell frame];
cellFrame.size.height = cell.friendActionView.frame.size.height;
[cell setFrame:cellFrame];
2、在table的heightForRowAtIndexPath中得到上述cell的高度:
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
<span style="white-space:pre"> </span>return cell.frame.size.height;
事实证明这种方法是行不通的。主要问题是heightForRowAtIndexPath这个委托的调用时机是早于cellForRowAtIndexPath这个委托方法的(此方法在UITableViewDataSource中定义)。如果按这样调用,会导致无限递归调用引发的堆栈溢出。解决方案有两种:
1、通过设置tableView的delegate解决。如下:
tableView.delegate=nil;
UITableViewCell *cell=[tableView cellForRowAtIndexPath:indexPath];
tableView.delegate=self;
2、在heightForRowAtIndexPath方法中,生成一个demoCell,通过绘制这个cell并得到其高度,就可以知道真正的cell高度。
最后我们的项目中使用的是方案一,因为考虑到cell的内容比较复杂,每一行都重绘一次开销很大。(实际使用的时候发现还是会调用两次,但不会引起递归调用了)