上一篇讲了懒加载的核心思想首先要理解UIScrollView的几个代理方法和调用顺序,那么这篇来写一下懒加载是如何实现的:
实现一个UITableView的数据加载,用一个占位图片和一个商品图片来做为演示,当需要加载的时候图片显示商品图片,不需要加载的时候显示的是占位图。(演示就不用网络请求来获取图片数据,所以也没有用到SDWebImage)
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellId"];
cell.imageView.image = [UIImage imageNamed:@"占位符"];
cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60;
}
开始实现懒加载:
- 首先要保证数据初始读取出来的时候,当前屏需要显示加载的图片,在cellForRowAtIndexPath方法中增加一段代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellId"];
cell.imageView.image = [UIImage imageNamed:@"占位符"];
cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];
if (!tableView.dragging && !tableView.decelerating) {
cell.imageView.image = [UIImage imageNamed:@"商品"];
}
return cell;
}
- 开始滑到的时候,这里分两种情况:
在讲两种情况之前,我们先写一个实现当前屏可见的cell加载图片的方法,如下:
- (void)showVisibleCellImage {
NSArray *visibleCellArray = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visibleCellArray) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:@"商品"];
}
}
上面方法实现后,继续
1)第一种情况:当拖动后手指离开,这个时候是有减速动画的,当减速动画快结束的时候,意思味着将要停止滚动了,这个时候显示当前屏幕的cell图片
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self showVisibleCellImage];
}
2)第二种情况:当拖动后手指不离开,这个时候是没有减速动画的。那么需要在scrollViewDidEndDragging来实现当前屏幕的cell图片
//这里的decelerate代表是否有减速动画,因为这里我需要实现的是没有减速动画的情况
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (!decelerate) {
[self showVisibleCellImage];
}
}
好了,懒加载的实现是不是看上去很简单,知道思路,写起来就很简单了。
其实懒加载还可以用另一种试来实现,而且实现起来更简单-----那就是RunLoop
RunLoop耳熟能知的两个model:1. NSDefaultRunLoopMode(默认mode);2. UITrackingRunLoopMode(滚动mode)
那么懒加载不正是滚动的时候我们不需要加载图片,而停下来的时候再加载图片。那么我们可以通过下面的一句代码即可实现懒加载:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellId"];
cell.imageView.image = [UIImage imageNamed:@"占位符"];
cell.textLabel.text = [NSString stringWithFormat:@"%ld",indexPath.row];
// if (!tableView.dragging && !tableView.decelerating) {
// cell.imageView.image = [UIImage imageNamed:@"商品"];
// }
[self performSelector:@selector(loadImageView:) withObject:indexPath afterDelay:0.f inModes:@[NSDefaultRunLoopMode]];
return cell;
}
运行一下是不是很简单,但是这里要知道RunLoop是基于线程的,这里用RunLoop会导致开销很大,所以不建议使用。
好了,到这里UITableView的懒加载就已经实现了,关于UITableView的其他优化,后续整理后再来写一下。