无图模式(省流量模式)的实现

在项目中为了提升用户体验,需要在2G/3G/4G网络情况下,提供一个无图模式(省流量模式)。我们的APP需求是:在用户开启了无图模式之后,如果当前网络是2G/3G/4G网络,则项目中加载图片的地方需要显示“点击加载图片”,当用户确认点击的情况下,才去加载图片。

无图模式下的判断逻辑如下:

  • 如果目标图片之前已经加载过了,则显示已经加载过的图片;
  • 如果目标图片之前没有加载过,则只显示一个placeholderImage,并且显示文案“点击加载图片”,当用户确认点击之后,再加载目标图片。

几点说明:

  • 为了方便管理图片以及判断图片是否已经加载过,这里使用第三方库SDWebImage来管理。
  • 网络情况判断推荐使用Reachability第三方库。

实现思路:

因为项目中之前已经使用了SDWebImage对图片进行管理,为了快速实现这个功能,这里创建了UIButton和UIImageView的扩展,并在扩展中新增了网络加载图片的方法。当开启了无图模式并且目标图片没有加载过时,将一个相同大小的UIButton---coverButton加在当前视图(UIButton或UIImageView)上,coverButton负责显示“点击加载图片”以及点击事件响应。

下面直接上代码(以UIButton为例):

#import "UIButton+YLNoImageModel.h"
#import "UIButton+WebCache.h"
#import "objc/runtime.h"
#import "UIImage+YLResize.h"

static void *kCoverButtonTag = &kCoverButtonTag;        ///< 覆盖按钮,点击加载
static void *kLoadImageUrl = &kLoadImageUrl;            ///< 图片url
static void *kHolderImage = &kHolderImage;              ///< 占位图片

@implementation UIButton (YLNoImageModel)
-(void)yl_setNoImageModelWithUrl:(NSURL *)url placeHolderImage:(UIImage *)holder
{
    UIImage *holderImg = [holder resizeToSize:self.bounds.size];
    
    if(kYLNoImageModeIsAvaliable){
        //开启了无图模式
        //异步判断是否已经加载过了当前图片
        [[SDWebImageManager sharedManager]cachedImageExistsForURL:url completion:^(BOOL isInCache) {
            if(isInCache){
                //如果已经加载过了,直接加载
                if(self.coverButton){
                    [self.coverButton removeFromSuperview];
                }
                
                [self sd_setImageWithURL:url forState:UIControlStateNormal
                        placeholderImage:holderImg];
            }else{
                //如果没有加载过,则显示点击查看显示图片
                [self setImage:holderImg forState:UIControlStateNormal];
                self.loadImageUrl = url;
                self.holderImage = holderImg;
                
                if(!self.coverButton){
                    self.coverButton = [UIButton buttonWithType:UIButtonTypeCustom];
                    self.coverButton.titleLabel.font = [UIFont systemFontOfSize:20];
                    [self.coverButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
                    [self.coverButton setTitle:@"点击加载图片" forState:UIControlStateNormal];
                    self.coverButton.contentMode = UIViewContentModeCenter;
                }
                [self.coverButton addTarget:self action:@selector(coverButtonAction) forControlEvents:UIControlEventTouchUpInside];
                self.coverButton.frame = self.bounds;
                [self addSubview:self.coverButton];
            }
        }];
    }else{
        //未开启无图模式
        if(self.coverButton){
            [self.coverButton removeFromSuperview];
        }
        
        [self sd_setImageWithURL:url forState:UIControlStateNormal placeholderImage:holderImg];
    }
}

-(UIButton *)coverButton
{
    return (UIButton *)objc_getAssociatedObject(self, kCoverButtonTag);
}

-(void)setCoverButton:(UIButton *)btn
{
    objc_setAssociatedObject(self, kCoverButtonTag, btn, OBJC_ASSOCIATION_RETAIN);
}

-(NSURL *)loadImageUrl
{
    return (NSURL *)objc_getAssociatedObject(self, kLoadImageUrl);
}

-(void)setLoadImageUrl:(NSURL *)url
{
    objc_setAssociatedObject(self, kLoadImageUrl, url, OBJC_ASSOCIATION_COPY);
}

-(UIImage *)holderImage
{
    return (UIImage *)objc_getAssociatedObject(self, kHolderImage);
}

-(void)setHolderImage :(UIImage *)img
{
    objc_setAssociatedObject(self, kHolderImage, img, OBJC_ASSOCIATION_RETAIN);
}

-(void)coverButtonAction
{
    if(self.coverButton){
        [self.coverButton removeFromSuperview];
    }
    
    [self sd_setImageWithURL:self.loadImageUrl forState:UIControlStateNormal placeholderImage:self.holderImage];
}

@end

至于网络条件判断,请参考Reachability,在项目中监听到网络改变之后保存一个标示kYLNoImageModeIsAvaliable在本地。

使用方法详见:YLNoImageModel

以上是我的实现方法,如果有其他更好的实现方法,请在文章后面留言告诉我一声,谢谢!

你可能感兴趣的:(无图模式(省流量模式)的实现)