Demo 下载
一、预览
二、如何使用(使用简单)
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;
三、库结构
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;
}