基于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欢迎指正

你可能感兴趣的:(基于SDWebImage实现的图片浏览器)