基于SDWebImage实现的图片浏览器

Demo 下载

一、预览

图片浏览.gif

二、如何使用(使用简单)

    CLPhotoBrowser *brower = [[CLPhotoBrowser alloc] init];
    brower.photos = [NSMutableArray array];
    int i=0;
    for (UIImageView *imageView in self.images) {
        CLPhoto *photo = [[CLPhoto alloc] init];
        NSString *url = [_urls[i] stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"bmiddle"];
        photo.url = url;
        photo.thumbUrl = _urls[i];
        photo.scrRect = [imageView convertRect:imageView.bounds toView:nil];
        [brower.photos addObject:photo];
        i++;
        
    }
    brower.selectImageIndex = tap.view.tag;
    [brower show];
    brower.delegate = self;
文件结构.png

三、库结构

CLPhotoBrowser:图片浏览器的容器,显示在window中的rootViewController
CLPhoto:保存图片URL和其他数据的数据模型
PhotoBrowserCell:UICollectionViewCell的子类,用于显示图片
CLPhotoProgressView:显示图片下载进度的View

四、内部实现

1、视图显示位置

- (void)show
{
    [[UIApplication sharedApplication].keyWindow endEditing:YES];

    UIViewController *rootViewCtl = [UIApplication sharedApplication].keyWindow.rootViewController;
    [rootViewCtl addChildViewController:self];
    [rootViewCtl.view addSubview:self.view];
    [self showFirstImageView];
}

2、显示第一张图片的动画

- (void)showFirstImageView
{
    CLPhoto *photo = [self.photos objectAtIndex:self.selectImageIndex];
    self.imageView = [[UIImageView alloc] init];
    [self.view addSubview:self.imageView];
    
    BOOL existBigPic = NO;
    self.imageView.image = [CLPhoto existImageWithUrl:photo.url];
    if (self.imageView.image) { //查看大图是否存在
        existBigPic = YES;
    }else{//查看小图是否存在
        self.imageView.image = [CLPhoto existImageWithUrl:photo.thumbUrl];
        if (self.imageView.image == nil) { //大小图都不存在时
            self.imageView.image = [UIImage imageNamed:@"dialog_load"];
        }
    }
    
    //渐变显示
    self.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.0];
    self.imageView.frame = photo.scrRect;
    __weak typeof(self)weakself = self;
    CGPoint ScreenCenter = self.view.window.center;

    [UIView animateWithDuration:duration animations:^{
        //有大图直接显示大图,没有先显示小图
        if (existBigPic) {
            CGSize size = [CLPhoto displaySize:self.imageView.image];
            weakself.imageView.frame = CGRectMake(0, 0, size.width, size.height);
            
            //长图处理
            if (size.height<=[UIScreen mainScreen].bounds.size.height) {
                weakself.imageView.center = ScreenCenter;
            }

        }else{
            self.imageView.center = self.view.center;
        }
        weakself.view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:1.0];

        
    } completion:^(BOOL finished) {
        [weakself.imageView removeFromSuperview];

        weakself.imageView = nil;
        weakself.collectionView.contentOffset = CGPointMake(self.selectImageIndex*[UIScreen mainScreen].bounds.size.width, 0);
        weakself.pageCtl.numberOfPages = self.photos.count;
        weakself.pageCtl.currentPage = self.selectImageIndex;
        weakself.currentSelectIndex = self.selectImageIndex;
        [_collectionView setContentOffset:(CGPoint){weakself.currentSelectIndex * (self.view.bounds.size.width + 20),0} animated:NO];

    }];
}

3、点击图片隐藏图片动画

- (void)hide:(UIImageView *)imageView with:(CLPhoto *)photo
{
    CGFloat width  = imageView.image.size.width;
    CGFloat height = imageView.image.size.height;
    
    CGSize tempRectSize = (CGSize){ScreenWidth,(height * ScreenWidth / width) > ScreenHeight ? ScreenHeight:(height * ScreenWidth / width)};
    
    [imageView setBounds:(CGRect){CGPointZero,{tempRectSize.width,tempRectSize.height}}];
    [imageView setCenter:self.view.center];
    [self.view addSubview:imageView];
    
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        [imageView setFrame:photo.scrRect];
        self.view.backgroundColor = [UIColor clearColor];
    } completion:^(BOOL finished) {
        [self.view removeFromSuperview];
        [self removeFromParentViewController];
    }];
}

4、给UIImageView添加手势

- (UIImageView *)imageView
{
    if (_imageView == nil) {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
        imageView.userInteractionEnabled = YES;

        
        // 1.生产 两种 手势
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDidTap)];
        UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDidDoubleTap:)];
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressToDo:)];
        
        // 2.设置 手势的要求
        [tap setNumberOfTapsRequired:1];
        [tap setNumberOfTouchesRequired:1];
        [doubleTap setNumberOfTapsRequired:2];
        [doubleTap setNumberOfTouchesRequired:1];
        
        // 3.避免两种手势冲突
        [tap requireGestureRecognizerToFail:doubleTap];
        
        // 4.添加 手势
        [self addGestureRecognizer:tap];
        [self addGestureRecognizer:doubleTap];
        [self addGestureRecognizer:longPress];
        
        
        [self.scrollview addSubview:imageView];
        _imageView = imageView;
        
    }
    return _imageView;
}

5、图片下载,先判断图片是否已经下载

- (UIImage *)image
{

    UIImage *urlImage = [CLPhoto existImageWithUrl:self.url];
    if (urlImage) {
        if (self.progressBlock) {
            self.progressBlock(1);
        }
        CGSize size = [CLPhoto displaySize:urlImage];
        self.imageViewBounds = CGRectMake(0, 0, size.width, size.height);
        return urlImage;
    }else{
        
        __weak typeof(self)weakself = self;
        [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:self.url] options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {
            if (weakself.progressBlock != nil) {

                CGFloat f = receivedSize*1.0 / expectedSize;
                weakself.progressBlock(f);
            }
        } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
            weakself.downLoad = YES;
        }];
        UIImage *thumbImage = [CLPhoto existImageWithUrl:self.thumbUrl];
        self.imageViewBounds = self.scrRect;
        return thumbImage;
    }

}

4、工具方法

(1)图片在手机上面按比例显示

+ (CGSize)displaySize:(UIImage *)image
{
    // 1.拿到图片的宽高比
    CGFloat imageW = image.size.width;
    CGFloat ScreenW = [UIScreen mainScreen].bounds.size.width;
    CGFloat scale = image.size.height / imageW;
    // 2.根据宽高比计算高度
    CGFloat width =  0;
    //最小UIImageView的显示宽度为100px
    if (imageW < 100) {
        width = 100;
    }else if (imageW > ScreenW) {
        width = ScreenW;
    }else{
        width = image.size.width;
    }
    CGFloat height =  width * scale;
    
    return CGSizeMake(width, height);
}

(2)判断图片是否在内存中或者缓存到沙盒中

+ (UIImage *)existImageWithUrl:(NSString *)urlStr
{
    SDWebImageManager *manager = [SDWebImageManager sharedManager];
    UIImage *image = nil;
    NSURL *url = [NSURL URLWithString:urlStr];
    NSString *key = [manager cacheKeyForURL:url];
    image = [manager.imageCache imageFromMemoryCacheForKey:key]; //先看看内存在是否存在图片
    if (!image) {
        image = [manager.imageCache imageFromDiskCacheForKey:key]; //重缓存中取出改图片
    }
    return image;
}

5、 有bug欢迎指正

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,979评论 4 60
  • 曾西翔阅读 283评论 0 1
  • 毕业两年多,一直在国企里工作,从最开始的WEB开发,到参与项目开发,到用户调研专员,最后又回归到项目管理,这当中的...
    朴老师87阅读 375评论 0 3
  • 前两天看了一个故事,大概就是讲一个女孩跟一个比她小的男孩在一起了,后来又分开了,后来这个男孩去世了的凄美爱情故事。...
    蹊言阅读 291评论 0 0