Demo下载以及个人Github地址: https://github.com/ChenNan-FRAM/WebImageViewBrowser
实现类似微博配图浏览功能:
- 点击全屏浏览大图
- 可用于单个ImageView也可用于多个ImageView
- 再次点击缩小回原位置
- 双指拖拉图片放大缩小
- 滑动浏览多个配图或上下滑动浏览
- 下载查看原图
- 保存到手机相册等
大致实现思路:
- 自定义UIImageView并添加手势点击功能实现响应点击动作;接受点击信号后传递给一个可全局调用的浏览类。
- 该类负责在windows窗口上添加一个ScrollView,如果只是单个图片则只需要在ScrollView上添加一个UIImageView,将大图原图的图片链接传入该类即可。如果是多个配图则需要在ScrollView上面添加一个ScrollView2,在ScrollView2上添加ImageView,再将大图原图的图片链接数组传入该类。
- 点击关闭的实现原理则是给最底下的ScrollView添加一个手势点击,将所有在ScrollView包括其自身设为全透明后从窗口移除。
- 在打开自定义UIImageView的时候要记录下打开时该ImageView的位置,以便动画返回原位置。
实现效果:
这里给出单个ImageView的情况下点击打开的Demo(图片下载的时候使用了第三方库SDWebImage,本Demo也有附上。可直接下载浏览):
自定义ImageView类:
SingleWebImageView.h部分:
//
// SingleWebImageView.h
// WebImageBrowserDemo
//
// Created by Caesar on 15/4/16.
// Copyright (c) 2015年 Caesar. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface SingleWebImageView : UIImageView
@property(nonatomic, copy)NSString *original_pic_url;
@property(nonatomic, copy)NSString *bmiddle_pic_url;
-(SingleWebImageView *)initWithStyleAndBmiddlePicUrl:(NSString *)bmiddle_pic_url andOriginalPicUrl:(NSString *)original_pic_url;
@end
SingleWebImageView.m部分:
//
// SingleWebImageView.m
// WebImageBrowserDemo
//
// Created by Caesar on 15/4/16.
// Copyright (c) 2015年 Caesar. All rights reserved.
//
#import "SingleWebImageView.h"
#import "SingleWebImageBrowser.h"
@implementation SingleWebImageView
#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]
- (SingleWebImageView *)initWithStyleAndBmiddlePicUrl:(NSString *)bmiddle_pic_url andOriginalPicUrl:(NSString *)original_pic_url{
self = [super init];
if (self) {
//ImageView样式自行定制
self.layer.cornerRadius = 5.0;
self.layer.masksToBounds = YES;
self.contentMode = UIViewContentModeScaleAspectFill;
self.backgroundColor = RGBACOLOR(220, 220, 220, 0.5);
//添加手势
self.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(showBmiddleImage:)];
[self addGestureRecognizer:tap];
self.bmiddle_pic_url = bmiddle_pic_url;
self.original_pic_url = original_pic_url;
}
return self;
}
//调用打开图片浏览器显示中图
-(void)showBmiddleImage:(NSString *)bmiddle_pic_url{
[[SingleWebImageBrowser sharedSingleWebImageBrowser]showBmiddlePic:self];
}
@end
SingleWebImageBrowser.h:
//
// SingleWebImageBrowser.h
// WebImageBrowserDemo
//
// Created by Caesar on 15/4/16.
// Copyright (c) 2015年 Caesar. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SingleWebImageView.h"
@interface SingleWebImageBrowser : NSObject
+(SingleWebImageBrowser *)sharedSingleWebImageBrowser;
-(void)showBmiddlePic:(SingleWebImageView *)webImageView;
-(void)closeBmiddlePic:(UITapGestureRecognizer *)tap;
@end
//
// SingleWebImageBrowser.m
// WebImageBrowserDemo
//
// Created by Caesar on 15/4/16.
// Copyright (c) 2015年 Caesar. All rights reserved.
//
#import "SingleWebImageBrowser.h"
#import "UIImageView+WebCache.h"
#define IPHONE_SCREEN_WIDTH [[UIScreen mainScreen]bounds].size.width
#define IPHONE_SCREEN_HEIGHT [[UIScreen mainScreen]bounds].size.height
#define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:(a)]
@interface SingleWebImageBrowser()<UIScrollViewDelegate>
{
UIWindow *window;
UIImageView *imageView;
UIScrollView *scrollView;
NSString *_bmiddle_pic_url;
NSString *_original_pic_url;
//
UIButton *downloadBtn;
UIButton *saveBtn;
//
UIActivityIndicatorView *waiting;
}
@end
@implementation SingleWebImageBrowser:NSObject
static CGRect oldImageViewFrame;
+(SingleWebImageBrowser *)sharedSingleWebImageBrowser{
static SingleWebImageBrowser *webImageBrowser;
@synchronized(self){
if (!webImageBrowser) {
webImageBrowser = [[self alloc]init];
}
}
return webImageBrowser;
}
-(void)showBmiddlePic:(SingleWebImageView *)webImageView{
_bmiddle_pic_url = webImageView.bmiddle_pic_url;
_original_pic_url = webImageView.original_pic_url;
//初始化控件
[self initComponent:webImageView];
[imageView addSubview:waiting];
[waiting startAnimating];
//使用SDWebImage异步下载并缓存图片
[imageView sd_setImageWithURL:[NSURL URLWithString:_bmiddle_pic_url]
placeholderImage:nil
options:SDWebImageProgressiveDownload
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){
//图片下载成功
if (image) {
[waiting stopAnimating];
imageView.image = image;
CGSize imageSize = image.size;
float b = imageSize.width/(IPHONE_SCREEN_WIDTH);
//依据下载图片尺寸调整显示
//如果按比例缩小图片后图片长仍然比屏幕长,则按照长度设置scrollview的垂直方向上的可拖动范围
if (imageSize.height/b >= IPHONE_SCREEN_HEIGHT) {
imageView.frame = CGRectMake(0, 20, IPHONE_SCREEN_WIDTH, imageSize.height/b);
scrollView.contentSize = CGSizeMake(imageView.frame.size.width, imageView.frame.size.height + 40);
}
else{
imageView.frame = CGRectMake(0, (IPHONE_SCREEN_HEIGHT - imageSize.height/b)/2, IPHONE_SCREEN_WIDTH, imageSize.height/b);
}
}
else{
[waiting stopAnimating];
}
}];
UITapGestureRecognizer *tap_closeScrollView = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(closeBmiddlePic:)];
[scrollView addGestureRecognizer:tap_closeScrollView];
//放大图片浏览器
[UIScrollView animateWithDuration:0.3 animations:^{
scrollView.alpha = 1;
}completion:^(BOOL finished){
}];
}
- (void)initComponent:(UIImageView *)webImageView{
window = [UIApplication sharedApplication].keyWindow;
downloadBtn = [UIButton buttonWithType:UIButtonTypeCustom];
downloadBtn.frame = CGRectMake(10, IPHONE_SCREEN_HEIGHT-40, 50, 25);
[downloadBtn setTitle:@"Original" forState:UIControlStateNormal];
[downloadBtn setFont:[UIFont systemFontOfSize:12]];
downloadBtn.layer.cornerRadius = 5.0;
downloadBtn.layer.masksToBounds = YES;
downloadBtn.backgroundColor = RGBACOLOR(20, 200, 40, 0.5);
[downloadBtn addTarget:self action:@selector(downloadOriginalPic) forControlEvents:UIControlEventTouchUpInside];
saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
saveBtn.frame = CGRectMake(70, IPHONE_SCREEN_HEIGHT-40, 50, 25);
[saveBtn setTitle:@"Save" forState:UIControlStateNormal];
[saveBtn setFont:[UIFont systemFontOfSize:12]];
saveBtn.layer.cornerRadius = 5.0;
saveBtn.layer.masksToBounds = YES;
saveBtn.backgroundColor = RGBACOLOR(20, 200, 40, 0.5);
[saveBtn addTarget:self action:@selector(saveImage) forControlEvents:UIControlEventTouchUpInside];
scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, IPHONE_SCREEN_WIDTH, IPHONE_SCREEN_HEIGHT)];
oldImageViewFrame = [webImageView convertRect:webImageView.bounds toView:window];
scrollView.backgroundColor = RGBACOLOR(150, 150, 150, 0.6);
scrollView.scrollEnabled = YES;
scrollView.showsVerticalScrollIndicator = YES;
scrollView.delegate = self;
scrollView.maximumZoomScale = 3.0;
scrollView.minimumZoomScale = 0.5;
imageView = [[UIImageView alloc]init];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.layer.cornerRadius = 5.0;
imageView.layer.masksToBounds = YES;
//设置tag值因为点击时需要按照tag获取点击的控件
imageView.tag = 901;
[scrollView addSubview:imageView];
[window addSubview:scrollView];
[window addSubview:downloadBtn];
[window addSubview:saveBtn];
waiting = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
waiting.center = CGPointMake(window.center.x, window.center.y);
[window addSubview:waiting];
}
//下载大图
- (void)downloadOriginalPic{
[waiting startAnimating];
[imageView sd_setImageWithURL:[NSURL URLWithString:_original_pic_url] placeholderImage:nil options:SDWebImageProgressiveDownload completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){
if (image) {
[waiting stopAnimating];
imageView.image = image;
CGSize imageSize = image.size;
float b = imageSize.width/(IPHONE_SCREEN_WIDTH);
if (imageSize.height/b >= IPHONE_SCREEN_HEIGHT) {
imageView.frame = CGRectMake(0, 20, IPHONE_SCREEN_WIDTH, imageSize.height/b);
scrollView.contentSize = CGSizeMake(imageView.frame.size.width, imageView.frame.size.height + 40);
}
else{
imageView.frame = CGRectMake(0, (IPHONE_SCREEN_HEIGHT - imageSize.height/b)/2, IPHONE_SCREEN_WIDTH, imageSize.height/b);
}
}
}];
}
//保存图片到相册
- (void)saveImage{
UIImageWriteToSavedPhotosAlbum([imageView image], nil, nil, nil);
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Reminder" message:@"图片已保存" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
-(void)closeBmiddlePic:(UITapGestureRecognizer *)tap{
UIScrollView *backgroundView = tap.view;
UIImageView *aimageView = (UIImageView *)[tap.view viewWithTag:901];
[UIScrollView animateWithDuration:0.3 animations:^{
aimageView.frame = oldImageViewFrame;
backgroundView.alpha = 0;
downloadBtn.alpha = 0;
saveBtn.alpha = 0;
}completion:^(BOOL finished){
[backgroundView removeFromSuperview];
[downloadBtn removeFromSuperview];
[saveBtn removeFromSuperview];
}];
}
//双指扩张放大图片
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)aScrollView{
if (aScrollView == scrollView) {
return imageView;
}
return nil;
}
//放大缩小调整图片位置使其不发生偏移
- (void)scrollViewDidZoom:(UIScrollView *)ascrollView{
if (ascrollView == scrollView) {
CGFloat offsetX = (ascrollView.bounds.size.width > ascrollView.contentSize.width)?
(ascrollView.bounds.size.width - ascrollView.contentSize.width) * 0.5 : 0.0;
CGFloat offsetY = (ascrollView.bounds.size.height > ascrollView.contentSize.height)?
(ascrollView.bounds.size.height - ascrollView.contentSize.height) * 0.5 : 0.0;
imageView.center = CGPointMake(ascrollView.contentSize.width * 0.5 + offsetX,
ascrollView.contentSize.height * 0.5 + offsetY);
}
}
@end