上一篇講了懶加載的核心思想首先要理解UIScrollView的幾個代理方法和調(diào)用順序,那么這篇來寫一下懶加載是如何實現(xiàn)的:
實現(xiàn)一個UITableView的數(shù)據(jù)加載,用一個占位圖片和一個商品圖片來做為演示彤路,當(dāng)需要加載的時候圖片顯示商品圖片,不需要加載的時候顯示的是占位圖暴浦。(演示就不用網(wǎng)絡(luò)請求來獲取圖片數(shù)據(jù),所以也沒有用到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;
}
開始實現(xiàn)懶加載:
- 首先要保證數(shù)據(jù)初始讀取出來的時候晓锻,當(dāng)前屏需要顯示加載的圖片歌焦,在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;
}
- 開始滑到的時候,這里分兩種情況:
在講兩種情況之前砚哆,我們先寫一個實現(xiàn)當(dāng)前屏可見的cell加載圖片的方法独撇,如下:
- (void)showVisibleCellImage {
NSArray *visibleCellArray = [self.tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visibleCellArray) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:@"商品"];
}
}
上面方法實現(xiàn)后,繼續(xù)
1)第一種情況:當(dāng)拖動后手指離開躁锁,這個時候是有減速動畫的纷铣,當(dāng)減速動畫快結(jié)束的時候,意思味著將要停止?jié)L動了战转,這個時候顯示當(dāng)前屏幕的cell圖片
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
[self showVisibleCellImage];
}
2)第二種情況:當(dāng)拖動后手指不離開关炼,這個時候是沒有減速動畫的。那么需要在scrollViewDidEndDragging來實現(xiàn)當(dāng)前屏幕的cell圖片
//這里的decelerate代表是否有減速動畫匣吊,因為這里我需要實現(xiàn)的是沒有減速動畫的情況
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (!decelerate) {
[self showVisibleCellImage];
}
}
好了儒拂,懶加載的實現(xiàn)是不是看上去很簡單,知道思路色鸳,寫起來就很簡單了社痛。
其實懶加載還可以用另一種試來實現(xiàn),而且實現(xiàn)起來更簡單-----那就是RunLoop
RunLoop耳熟能知的兩個model:1. NSDefaultRunLoopMode(默認(rèn)mode)命雀;2. UITrackingRunLoopMode(滾動mode)
那么懶加載不正是滾動的時候我們不需要加載圖片蒜哀,而停下來的時候再加載圖片。那么我們可以通過下面的一句代碼即可實現(xiàn)懶加載:
- (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會導(dǎo)致開銷很大,所以不建議使用狐血。
好了淀歇,到這里UITableView的懶加載就已經(jīng)實現(xiàn)了,關(guān)于UITableView的其他優(yōu)化匈织,后續(xù)整理后再來寫一下浪默。