iOS:UITableView的優(yōu)化篇-懶加載(二)

上一篇講了懶加載的核心思想首先要理解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)懶加載:

  1. 首先要保證數(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;
}
  1. 開始滑到的時候,這里分兩種情況:
    在講兩種情況之前,我們先寫一個實現(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;
}

運(yùn)行一下是不是很簡單,但是這里要知道RunLoop是基于線程的,這里用RunLoop會導(dǎo)致開銷很大,所以不建議使用。

好了,到這里UITableView的懶加載就已經(jīng)實現(xiàn)了,關(guān)于UITableView的其他優(yōu)化,后續(xù)整理后再來寫一下。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容