美文网首页
tableView 图片的延迟加载(基于SDWebImage)

tableView 图片的延迟加载(基于SDWebImage)

作者: silence_xz | 来源:发表于2017-04-26 20:46 被阅读230次

当我们使用手机刷微博和看新闻的时候,经常滑过不太关注的内容,也许你也发现了,跳过的内容中的图片很多显示的是默认图,并没有网络加载图片,这个是一个比较好的体验,一方面不需要加载太多的内容,可以减少用户的流量,体验也更加流畅;另一方面也减轻了服务器的压力。一举两得,何乐而不为。

所以想实现这个效果,经过一番的检索[站在巨人的肩膀上],找到了一个不错的博客 lazy懒加载(延迟加载)UITableView ,因为是自己实现的下载图片和缓存,而我应用中使用的是基于SDWebImage方式的,所以我做了些改动,希望能帮到你。

原理博客中介绍的很清楚了,在停止滑动的时候,再进行加载当前窗口中cell的图片,而不是全部cell中的图片,加载结束时进行图片缓存,下次刷新的时候直接从缓存中取得图片。

首先在对应的model中多增加了一个UIImage类型的属性,用于获取缓存图片。

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface PhotoModel : NSObject

@property(copy,nonatomic)NSString *photoPath;


@property(strong,nonatomic)UIImage  *photoImg;



@end

#import "PhotoModel.h"
#import "UIImageView+WebCache.h"

@implementation PhotoModel

- (UIImage *)photoImg
{
    
    if (self.photoPath) { // 如果缓存中有,就从缓存中获取
        
        NSURL  *pathUrl = [NSURL URLWithString:self.photoPath];

        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        [manager diskImageExistsForURL:pathUrl];
        
        _photoImg = [[manager imageCache] imageFromDiskCacheForKey:pathUrl.absoluteString];
    }
    
    return _photoImg;
}

@end


然后,在滑动结束时,进行加载图片就可以了

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"PhotoTableViewCell";
    PhotoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    
    if (cell == nil) {
        
        cell = [[PhotoTableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
    }
    
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
    PhotoModel *model = [self.dataArray objectAtIndex:indexPath.row];
    
    if (model.photoImg == nil) {
        
        // 缓存中没有,去下载吧
        cell.photoImgView.image = nil;
        
        NSLog(@"dragging = %d,decelerating = %d",self.tableView.dragging,self.tableView.decelerating);
        // 停止拖拽或者滑动结束时,加载当前cell对应的图片
        if (self.tableView.dragging == NO && self.tableView.decelerating == NO) {
            
            [self startPicDownload:model forIndexPath:indexPath];
        }
        
    }else{
        
        // 缓存中直接显示出来
        cell.photoImgView.image = model.photoImg;
    }
    
    return cell;
}

- (void)startPicDownload:(PhotoModel *)model forIndexPath:(NSIndexPath *)indexPath{
    
    UIImageView *tappedImageView = [[UIImageView alloc]init];
    NSURL  *pathUrl = [NSURL URLWithString:model.photoPath];

    [tappedImageView sd_setImageWithURL:pathUrl placeholderImage:nil options:SDWebImageProgressiveDownload completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
        
        tappedImageView.image = image;
        
        // 根据indexPath获取cell对象,并加载图像
        PhotoTableViewCell * cell = (PhotoTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        
        cell.photoImgView.image = image;
    }];
}

#pragma mark - 延迟加载关键
//tableView停止拖拽,停止滚动
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //如果tableview停止滚动,开始加载图像
    if (!decelerate) {
        
        [self loadImagesForOnscreenRows];
    }
    NSLog(@"%s__%d__|%d",__FUNCTION__,__LINE__,decelerate);
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    //如果tableview停止滚动,开始加载图像
    [self loadImagesForOnscreenRows];
}

- (void)loadImagesForOnscreenRows
{
    //获取tableview正在window上显示的cell,加载这些cell上图像。通过indexPath可以获取该行上需要展示的cell对象
    NSArray * visibleCells = [self.tableView indexPathsForVisibleRows];
    for (NSIndexPath * indexPath in visibleCells) {
        
        PhotoModel *model = [self.dataArray objectAtIndex:indexPath.row];
        if (model.photoImg == nil) {
            
            //如果还没有下载图像,开始下载
            [self startPicDownload:model forIndexPath:indexPath];
        }
    }
}

DEMO

相关文章

网友评论

      本文标题:tableView 图片的延迟加载(基于SDWebImage)

      本文链接:https://www.haomeiwen.com/subject/mfjwzttx.html