卡顿原因:cell赋值内容时,会根据内容设置布局,也就可以知道cell的高度,若有1000行,就会调用1000次 cellForRow方法,而我们对cell的处理操作,都是在这个方法中赋值,布局等等,开销很大。
1.提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法
在获得数据后,直接先根据数据源计算出对应的布局,并缓存到数据源中,这样在tableView:heightForRowAtIndexPath:方法中就直接返回高度,而不需要每次都计算了
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dict = self.dataList[indexPath.row];
CGRect rect = [dict[@"frame"] CGRectValue];
return rect.frame.height;
}
2.==赋值和计算布局分离==。cellForRow负责赋值,heightRorRow负责计算高度。
3.自定义cell绘制异步绘制
给自定义的Cell添加draw方法
采用异步绘制,如果在重写drawRect方法就不需要用GCD异步线程了,因为drawRect本来就是异步绘制的。
4.滑动UITableView时,按需加载对应的内容(大量图片展示,网络加载的时候很管用)
//按需加载 - 如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载。
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
NSIndexPath *ip = [self indexPathForRowAtPoint:CGPointMake(0, targetContentOffset->y)];
NSIndexPath *cip = [[self indexPathsForVisibleRows] firstObject];
NSInteger skipCount = 8;
if (labs(cip.row-ip.row)>skipCount) {
NSArray *temp = [self indexPathsForRowsInRect:CGRectMake(0, targetContentOffset->y, self.width, self.height)];
NSMutableArray *arr = [NSMutableArray arrayWithArray:temp];
if (velocity.y<0) {
NSIndexPath *indexPath = [temp lastObject];
if (indexPath.row+33) {
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-3 inSection:0]];
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-2 inSection:0]];
[arr addObject:[NSIndexPath indexPathForRow:indexPath.row-1 inSection:0]];
}
}
[needLoadArr addObjectsFromArray:arr];
}
}
//在tableView:cellForRowAtIndexPath:方法中加入判断:
if (needLoadArr.count>0&&[needLoadArr indexOfObject:indexPath]==NSNotFound) {
[cell clear];
return;
}
滚动很快时,只加载目标范围内的Cell,这样按需加载,极大的提高流畅度。