UITableView是iOS开发中的常用控件,用来加载列表数据,当数据量大或者布局过于复杂的时候有可能出现卡顿,影响用户体验。
缓存高度
UITableView 的 UITableViewDelegate 里面有个方法 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
专门用于获取 Cell 的高度 。由于UITableView在绘制 Cell 的时候每次会主动获取 Cell 的高度,所以这里的优化点是减少该方法的执行时间。保存第一次计算出来的 Cell 高度,并保存到 Cell 对应的 Model 上 ,而不是每次重复计算 Cell 的高度,可以达到减少该方法的执行时间的目的。
异步渲染UITableViewCell
如果一个UITableViewCell使用系统自带的View进行布局的层级很多时,可以考虑对TableViewCell进行优化,减少View的层级,也就是对TableViewCell异步渲染。
按需加载UITableViewCell
判断按需加载的 indexPaths , 如果目标行与当前行相差超过指定行数,只在目标滚动范围的前后指定3行加载。这样可以减少 UITableView 的绘制工作量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| - (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+3<datas.count) { [arr addObject:[NSIndexPath indexPathForRow:indexPath.row+1 inSection:0]]; [arr addObject:[NSIndexPath indexPathForRow:indexPath.row+2 inSection:0]]; [arr addObject:[NSIndexPath indexPathForRow:indexPath.row+3 inSection:0]]; } } else { NSIndexPath *indexPath = [temp firstObject]; if (indexPath.row>3) { [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]; } }
|
当 UITableView 开始绘制 Cell 的时候,若是 indexpath 包含在按需绘制的 needLoadArr 数组里面,那么就异步绘制该 Cell ,如果没有则跳过该 Cell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ VVeboTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; if (cell==nil) { cell = [[VVeboTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; } [self drawCell:cell withIndexPath:indexPath]; return cell; }
- (void)drawCell:(VVeboTableViewCell *)cell withIndexPath:(NSIndexPath *)indexPath{ NSDictionary *data = [datas objectAtIndex:indexPath.row]; cell.selectionStyle = UITableViewCellSelectionStyleNone; [cell clear]; cell.data = data; if (needLoadArr.count>0&&[needLoadArr indexOfObject:indexPath]==NSNotFound) { [cell clear]; return; } if (scrollToToping) { return; } [cell draw]; }
|
参考
1.UITableView 的优化技巧
2. Code