美文网首页
UITableView 刷新

UITableView 刷新

作者: 05fad25aea68 | 来源:发表于2018-01-31 17:14 被阅读91次

UITableView指定cell刷新问题调研(环境xcode9+IOS10、11)

一般UITableView需要刷新的时候调用reloadData即可刷新整个列表。但这么刷新,首先性能并不高,其次在一些特殊场景下,也无法达到效果。所以有时候需要仅仅刷新某几行的cell,某个section的全部cell,或者仅仅是刷新某一行cell。这时候需要调用:

- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

这类API其实有个要求的,操作之前的cell和操作之后的cell 不能是同一个cell。 官方文档是这么说的:


image.png

意思是reloadRowsAtIndexPaths会调用data source,为这一行重新创建一个全新的cell,然后根据动画替换旧的cell。类似下面这种复用cell的写法不会有任何问题。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    switch (indexPath.row) {
    static NSString *ideitifier = @"tgCell";
    TgCell *cell = [tableViewdequeueReusableCellWithIdentifier:ideitifier];
    if (!cell) {
cell = [[TgCell alloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:ideitifier];
// do something
    }
    return cell;
}

如果是返回固定的cell,类似下面的写法,就会出现问题。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (indexPath.row == 0){
      return self.firstCell;
    }
}

这时候用reloadRowsAtIndexPaths刷新row=0的时候,调用data source得到的是同一个cell,指向同一个内存空间。会发生一些不可预见的问题:根据animation参数的不同。

UITableViewRowAnimationNone 没有动画的情况,cell有可能不刷新,或出现空白区域
UITableViewRowAnimationRight 有动画的情况,cell会有消失动画,然后不再显示。刷新的话会重新出现。

reloadData 和 reloadRowsAtIndexPaths 需要注意的区别:reloadRowsAtIndexPaths执行过程中,需要 'blends' 旧cell 和 新cell,就是同时需要这两个cell,如果两个cell是指向同一个,就会出现问题。或者有一个是nil,也会出现surprise!stockflow相关回答

image.png

另外发现一个: reloadRowsAtIndexPaths 一个cell的时候,会把相关的其他的cell状态刷新成正确的。所以一直没发现项目中的一个隐患。刷新一组cell,最后一个cell是复用的,所以会使得所有的cell都被正常刷新,没有问题。

ps.有的时候仅仅是高度问题,想刷新cell的高度,网上很多人都这么用:


image.png

貌似是没什么问题,能达到效果。 但是官方api是明确说了,这样做可能会出现问题。所以这样做是有隐患的。


image.png

相关文章

网友评论

      本文标题:UITableView 刷新

      本文链接:https://www.haomeiwen.com/subject/bwdlzxtx.html