优化UItableView的更多细节

1,异步加载数据。防止主线程进入假死状态,造成表格卡顿现象!

2,cell的复用机制,避免大量的产生cell对象造成内存过大以及对象的释放问题!

3,UITableViewdataSource中实现的tableView:cellForRowAtIndexPath:方法,需要为每个cell调用一次,它应该快速执行。所以你需要尽可能快地返回重用cell实例。所以:不要在这里去执行数据绑定,因为目前在屏幕上还没有cell。为了执行数据绑定,可以在UITableViewdelegate方法tableView:willDisplayCell:forRowAtIndexPath:中进行。这个方法在显示cell之前会被调用。

4,同样的道理:UITableViewdelegate方法tableView:heightForRowAtIndexPath:会为每个cell调用一次,所以你应该非常快地返回高度值。很多人会犯一个错误,他们会在布局初始化cell实例并绑定数据后去获取它们的高度。如果你想优化滑动的性能,就不应该以这种方式来计算cell的高度,因为这事难以置信的低效,iOS设备标准的60 FPS将会降低到15-20 FPS,滑动会变得很慢。

所以当你自定义cell的时候应该有一个借口返回自己的高度:

  • 当我们的数据未能显示满一屏幕的时候,UITableView会显示多余的横线,这个时候你如果希望去掉这些横线,你可以加上这句话。

self.tableView.tableFooterView = [[UIView alloc]init];

  • UITableView的分割线默认是开头空15像素点的(好像是15来着~~),产品经理有时候希望能够定格显示,那么你可能会这么做。

  •    self.tableView.separatorInset = UIEdgeInsetsZero;


但是你很快就会发现这么做并没有效果,这是因为separatorInset这个属性在iOS7以后就已经失效了,但是我们还是能够达到同样的效果,你可以在你的tablevView的代理协议实现界面加上下面这段代码:


/**

*  分割线顶头

*/

-(void)viewDidLayoutSubviews

{

  if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {

      [self.tableView setSeparatorInset:UIEdgeInsetsMake(0,0,0,0)];

  }

 

  if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {

      [self.tableView setLayoutMargins:UIEdgeInsetsMake(0,0,0,0)];

  }

}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

{

  if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {

      [cell setSeparatorInset:UIEdgeInsetsZero];

  }

  if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {

      [cell setLayoutMargins:UIEdgeInsetsZero];

  }

}

很多情况下我们的UITableViewCell的高度是动态不确定的,比如说很多聊天的界面都需要我们去动态的计算cell的高度,你可能会在heightForRowAtIndexPath代理协议方法中返回你计算好的cell高度,然后在苹果推出约束以后,我们其实有更加方便的方法去实现相同的效果。你可以尝试在你的代码中加入以下两行代码:


self.tableView.estimatedRowHeight = 68.0;

self.tableView.rowHeight = UITableViewAutomaticDimension;


再次运行你的程序,其实你发现了好像你的cell并没有动态的返回高度,这是因为上面说了,这两行代码必须配合约束来使用。


我们拖出一个SB,然后在cell上放上一个label,讲label的numberOfLines属性设置为0,然后设置好label的上下左右约束,然后再对label的内容进行赋值,再次运行你的程序,这个时候你的cell就会动态的显示高度了,label的高度取决于你的内容的多少,同时按照你的约束进行显示


-你可能写过这样下面这样的代码


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

  [tableView deselectRowAtIndexPath:indexPath animated:true];

  [tableView beginUpdates];

  ROW--;//此操作表示减少数据源的个数。

  [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationRight];

  [tableView endUpdates];

}


用一个动画来删除某一个cell,其中有两行代码特别有意思:


[tableView beginUpdates];

[tableView endUpdates];

你可能会经常忽略UITableView的一些属性和回调,必须下面这个方法:


-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

  CGFloat offSet = tableView.contentOffset.y;

  if (offSet<=0) {

      return;

  }

  CGRect oldRect = cell.frame;

  CGRect newRect = cell.frame;

  newRect.origin.x += 50;

  cell.frame = newRect;

  [UIView animateWithDuration:0.5 animations:^{

      cell.frame = oldRect;

  }];

}


如果你这么写会简单的有一个展示的动画,这个回调就是在cell展示到屏幕的时候发起的动作。

还有这个属性:tableView.visibleCells,你的产品经理可能会要求你的cell在滚动的时候进行一些展示类的动画—-滚动的时候进行展开收起之类的,这样的话你可以这么做:


-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

  for (UITableViewCell *cell in _tableView.visibleCells) {

      /**

       *  你可以在这里对当前的cell进行一些操作

       *

       */

  }

}


这个属性会返回即将展示到屏幕上的cell,而放在这个滚动的回掉中你就可以对你的cell进行不停的调整了,具体能做出什么动画,就靠你的想象能力了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值