注意:
使用UITableView时,一般均需配置UITableView的两个代理(UITableViewDelegate与UITableViewDataSource)。
UITableViewDelegate:用于管理cell显示的自定义化设置(cell将要显示时的配置),cell的行高设置,cell的头,尾部的数据展示等等。
UITableViewDataSource:UITableView的数据源,用于配制UITableView有多少行数据(视图),以及每行的数据是怎样的。
一:UITableViewDelegate与UITableViewDataSource必须实现的代理方法:
UITableViewDelegate中的代理方法均是可选实现的;
UITableViewDataSource中的代理方法除配置cell的行数,及配置UITableViewCell为必须实现外,其余均为可选实现。
二:UITableViewDelegate与UITableViewDataSource代理的调用顺序:
实例:(一个section,两个row)
2019-02-18 12:00:24.348517+0800 TWTableviewDemo[26867:686352] -[ViewController tableView:numberOfRowsInSection:]
2019-02-18 12:00:24.348633+0800 TWTableviewDemo[26867:686352] -[ViewController tableView:heightForRowAtIndexPath:]
2019-02-18 12:00:24.348837+0800 TWTableviewDemo[26867:686352] -[ViewController tableView:heightForRowAtIndexPath:]
2019-02-18 12:00:24.349136+0800 TWTableviewDemo[26867:686352] -[ViewController tableView:cellForRowAtIndexPath:]
2019-02-18 12:00:24.352160+0800 TWTableviewDemo[26867:686352] -[ViewController tableView:heightForRowAtIndexPath:]
2019-02-18 12:00:24.359344+0800 TWTableviewDemo[26867:686352] -[ViewController tableView:cellForRowAtIndexPath:]
2019-02-18 12:00:24.360997+0800 TWTableviewDemo[26867:686352] -[ViewController tableView:heightForRowAtIndexPath:]
结论:
对于cellHeight,cellRow以及cell代理方法配置的调用顺序如下:
1):调用numberOfRow代理方法,执行一次;
2):调用heightForRowAtIndexPath代理方法,执行rowCount次;
(如果设置estimatedRowHeight预估高度为0,则步骤2会执行;如果设置estimatedRowHeight不为0,则步骤2不执行)
3):调用cellForRowAtIndexPath代理方法,执行visiableRowCount(最大显示cell行数)次;
(每次调用一次cellForRowAtIndexPath方法时,均会相应地调用一次heightForRowAtIndexPath)
三:cell动态高度自适应的实现及原因:
实现:
因为,model数据获取先于cell高度的设置,所以,可以在model中通过各文本,图片来计算相应cell的高度;
又因为,cell内容的设置先于cell高度的设置,所以,可以在cell中异步获取图片,计算网络图片的高度,进而计算相应cell的高度。
综上所述,我们可以在model中,计算文本,图片高度,进而计算出cell的高度,然后将cell的高度缓存在model中。这样,在heightForRowAtIndexPath代理方法中,直接使用model中的cellHeight。
原因:
1):每次cell滑出(滑入)屏幕,均会先调用一次cellForRowAtIndexPath,再调用一次heightForRowAtIndexPath;这样heightForRowAtIndexPath会执行多次,为了避免重复计算cell的高度;所以,在model中缓存cell的高度非常必要;
2):如果是网络图片,图片高度不确定,怎么设置cell动态高度???
四:cell固定高度时:
强烈建议使用 self.tableView.rowHeight = 44; 等API来设置固定高度,不推荐使用heightForRowAtIndexPath代理方法。原因则是,cell的heightForRowAtIndexPath代理方法会多次重复调用(每个cell移出,移入屏幕时,均会调用该方法)。
五:计算各视图尺寸相关:
[label sizeToFit]:sizeToFit会计算出view最优的尺寸,并且会改变view的尺寸;
[label sizeThatFits:CGSizeZero]:sizeThatFits也会计算出view最优的尺寸,但是不会改变view的尺寸;
若想计算出label的尺寸,则需要对label添加约束,或者是设置label的最大宽度preferredMaxLayoutWidth;