图片放大预览(支持多张,支持双击放大)
使用方法
JZAlbumViewController *album = [[JZAlbumViewController alloc] init];
album.imgArr = self.imgsArray;//可以是图片的url字符串数组,亦可以是UIImage
album.currentIndex = tap.view.tag-100; //下标
[self presentViewController:album animated:YES completion:nil];
源码(或者去文件中下载)
// // JZAlbumViewController.h // aoyouHH // 功能描述:用于显示并浏览图片,添加了加载进度条功能 // Created by jinzelu on 15/4/27. // Copyright (c) 2015年 jinzelu. All rights reserved. // #import <UIKit/UIKit.h> @interface JZAlbumViewController : UIViewController /** * 接收图片数组,数组类型可以是url数组,image数组 */ @property(nonatomic, strong) NSMutableArray *imgArr; /** * 显示scrollView */ @property(nonatomic, strong) UIScrollView *scrollView; /** * 显示下标 */ @property(nonatomic, strong) UILabel *sliderLabel; /** * 接收当前图片的序号,默认的是0 */ @property(nonatomic, assign) NSInteger currentIndex; @end
// // JZAlbumViewController.m // aoyouHH // // Created by jinzelu on 15/4/27. // Copyright (c) 2015年 jinzelu. All rights reserved. // #import "JZAlbumViewController.h" #import "UIImageView+WebCache.h" #import "PhotoView.h" #define screen_width [UIScreen mainScreen].bounds.size.width #define screen_height [UIScreen mainScreen].bounds.size.height @interface JZAlbumViewController ()<UIScrollViewDelegate,PhotoViewDelegate> { CGFloat lastScale; NSMutableArray *_subViewList; } @end @implementation JZAlbumViewController -(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // _subViewList = [[NSMutableArray alloc] init]; } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. lastScale = 1.0; self.view.backgroundColor = [UIColor blackColor]; // UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(OnTapView)]; // [self.view addGestureRecognizer:tap]; [self initScrollView]; [self addLabels]; [self setPicCurrentIndex:self.currentIndex]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)initScrollView{ // [[SDImageCache sharedImageCache] cleanDisk]; // [[SDImageCache sharedImageCache] clearMemory]; self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, screen_width, screen_height)]; self.scrollView.pagingEnabled = YES; self.scrollView.userInteractionEnabled = YES; self.scrollView.showsHorizontalScrollIndicator = NO; self.scrollView.contentSize = CGSizeMake(self.imgArr.count*screen_width, screen_height); self.scrollView.delegate = self; self.scrollView.contentOffset = CGPointMake(0, 0); //设置放大缩小的最大,最小倍数 // self.scrollView.minimumZoomScale = 1; // self.scrollView.maximumZoomScale = 2; [self.view addSubview:self.scrollView]; for (int i = 0; i < self.imgArr.count; i++) { [_subViewList addObject:[NSNull class]]; } } -(void)addLabels{ self.sliderLabel = [[UILabel alloc] initWithFrame:CGRectMake(40, screen_height-64-49, 60, 30)]; self.sliderLabel.backgroundColor = [UIColor clearColor]; self.sliderLabel.textColor = [UIColor whiteColor]; self.sliderLabel.text = [NSString stringWithFormat:@"%ld/%lu",self.currentIndex+1,(unsigned long)self.imgArr.count]; [self.view addSubview:self.sliderLabel]; } -(void)setPicCurrentIndex:(NSInteger)currentIndex{ _currentIndex = currentIndex; self.scrollView.contentOffset = CGPointMake(screen_width*currentIndex, 0); [self loadPhote:_currentIndex]; [self loadPhote:_currentIndex+1]; [self loadPhote:_currentIndex-1]; } -(void)loadPhote:(NSInteger)index{ if (index<0 || index >=self.imgArr.count) { return; } id currentPhotoView = [_subViewList objectAtIndex:index]; if (![currentPhotoView isKindOfClass:[PhotoView class]]) { //url数组 CGRect frame = CGRectMake(index*_scrollView.frame.size.width, 0, self.view.frame.size.width, self.view.frame.size.height); PhotoView *photoV = [[PhotoView alloc] initWithFrame:frame withPhotoUrl:[self.imgArr objectAtIndex:index]]; photoV.delegate = self; [self.scrollView insertSubview:photoV atIndex:0]; [_subViewList replaceObjectAtIndex:index withObject:photoV]; }else{ PhotoView *photoV = (PhotoView *)currentPhotoView; } } #pragma mark - PhotoViewDelegate -(void)TapHiddenPhotoView{ [self dismissViewControllerAnimated:YES completion:nil]; } -(void)OnTapView{ [self dismissViewControllerAnimated:YES completion:nil]; } //手势 -(void)pinGes:(UIPinchGestureRecognizer *)sender{ if ([sender state] == UIGestureRecognizerStateBegan) { lastScale = 1.0; } CGFloat scale = 1.0 - (lastScale -[sender scale]); lastScale = [sender scale]; self.scrollView.contentSize = CGSizeMake(self.imgArr.count*screen_width, screen_height*lastScale); NSLog(@"scale:%f lastScale:%f",scale,lastScale); CATransform3D newTransform = CATransform3DScale(sender.view.layer.transform, scale, scale, 1); sender.view.layer.transform = newTransform; if ([sender state] == UIGestureRecognizerStateEnded) { // } } #pragma mark - UIScrollViewDelegate -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ NSLog(@"scrollViewDidEndDecelerating"); int i = scrollView.contentOffset.x/screen_width+1; [self loadPhote:i-1]; self.sliderLabel.text = [NSString stringWithFormat:@"%d/%lu",i,(unsigned long)self.imgArr.count]; } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end
// // PhotoView.h // aoyouHH // // Created by jinzelu on 15/4/30. // Copyright (c) 2015年 jinzelu. All rights reserved. // #import <UIKit/UIKit.h> //1. @protocol PhotoViewDelegate <NSObject> //点击图片时,隐藏图片浏览器 -(void)TapHiddenPhotoView; @end @interface PhotoView : UIView /** * 添加的图片 */ @property(nonatomic, strong) UIImageView *imageView; //2. /** * 代理 */ @property(nonatomic, assign) id<PhotoViewDelegate> delegate; -(id)initWithFrame:(CGRect)frame withPhotoUrl:(NSString *)photoUrl; -(id)initWithFrame:(CGRect)frame withPhotoImage:(UIImage *)image; @end
// // PhotoView.m // aoyouHH // // Created by jinzelu on 15/4/30. // Copyright (c) 2015年 jinzelu. All rights reserved. // #import "PhotoView.h" #import "UIImageView+WebCache.h" #import "SVProgressHUD.h" @interface PhotoView ()<UIScrollViewDelegate> { UIScrollView *_scrollView; } @end @implementation PhotoView -(id)initWithFrame:(CGRect)frame withPhotoUrl:(NSString *)photoUrl{ self = [super initWithFrame:frame]; if (self) { //添加scrollView _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; _scrollView.delegate = self; _scrollView.minimumZoomScale = 1; _scrollView.maximumZoomScale = 3; _scrollView.showsHorizontalScrollIndicator = NO; _scrollView.showsVerticalScrollIndicator = NO; [self addSubview:_scrollView]; //添加图片 self.imageView = [[UIImageView alloc] initWithFrame:self.bounds]; self.imageView.contentMode = UIViewContentModeScaleAspectFit; SDWebImageManager *manager = [SDWebImageManager sharedManager]; BOOL isCached = [manager cachedImageExistsForURL:[NSURL URLWithString:photoUrl]]; if (!isCached) {//没有缓存 // hud = [MBProgressHUD showHUDAddedTo:self animated:YES]; // hud.mode = MBProgressHUDModeDeterminate; [SVProgressHUD showProgress:0]; } [self.imageView sd_setImageWithURL:[NSURL URLWithString:photoUrl] placeholderImage:[UIImage imageNamed:@"loading"] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize){ [SVProgressHUD showProgress:((float)receivedSize)/expectedSize]; } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){ NSLog(@"图片加载完成"); if (!isCached) { [SVProgressHUD dismiss]; } }]; [self.imageView setUserInteractionEnabled:YES]; [_scrollView addSubview:self.imageView]; //添加手势 UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)]; UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)]; singleTap.numberOfTapsRequired = 1; singleTap.numberOfTouchesRequired = 1; doubleTap.numberOfTapsRequired = 2;//需要点两下 twoFingerTap.numberOfTouchesRequired = 2;//需要两个手指touch [self.imageView addGestureRecognizer:singleTap]; [self.imageView addGestureRecognizer:doubleTap]; [self.imageView addGestureRecognizer:twoFingerTap]; [singleTap requireGestureRecognizerToFail:doubleTap];//如果双击了,则不响应单击事件 [_scrollView setZoomScale:1]; } return self; } -(id)initWithFrame:(CGRect)frame withPhotoImage:(UIImage *)image{ self = [super initWithFrame:frame]; if (self) { //添加scrollView _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; _scrollView.delegate = self; _scrollView.minimumZoomScale = 1; _scrollView.maximumZoomScale = 3; _scrollView.showsHorizontalScrollIndicator = NO; _scrollView.showsVerticalScrollIndicator = NO; [self addSubview:_scrollView]; //添加图片 self.imageView = [[UIImageView alloc] initWithFrame:self.bounds]; self.imageView.contentMode = UIViewContentModeScaleAspectFit; [self.imageView setImage:image]; [self.imageView setUserInteractionEnabled:YES]; [_scrollView addSubview:self.imageView]; //添加手势 UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)]; UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)]; singleTap.numberOfTapsRequired = 1; singleTap.numberOfTouchesRequired = 1; doubleTap.numberOfTapsRequired = 2;//需要点两下 twoFingerTap.numberOfTouchesRequired = 2;//需要两个手指touch [self.imageView addGestureRecognizer:singleTap]; [self.imageView addGestureRecognizer:doubleTap]; [self.imageView addGestureRecognizer:twoFingerTap]; [singleTap requireGestureRecognizerToFail:doubleTap];//如果双击了,则不响应单击事件 [_scrollView setZoomScale:1]; } return self; } #pragma mark - UIScrollViewDelegate //scroll view处理缩放和平移手势,必须需要实现委托下面两个方法,另外 maximumZoomScale和minimumZoomScale两个属性要不一样 //1.返回要缩放的图片 -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{ return self.imageView; } //2.重新确定缩放完后的缩放倍数 -(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{ [scrollView setZoomScale:scale+0.01 animated:NO]; [scrollView setZoomScale:scale animated:NO]; } #pragma mark - 图片的点击,touch事件 -(void)handleSingleTap:(UITapGestureRecognizer *)gestureRecognizer{ NSLog(@"单击"); if (gestureRecognizer.numberOfTapsRequired == 1) { [self.delegate TapHiddenPhotoView]; } } -(void)handleDoubleTap:(UITapGestureRecognizer *)gestureRecognizer{ NSLog(@"双击"); if (gestureRecognizer.numberOfTapsRequired == 2) { if(_scrollView.zoomScale == 1){ float newScale = [_scrollView zoomScale] *2; CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; [_scrollView zoomToRect:zoomRect animated:YES]; }else{ float newScale = [_scrollView zoomScale]/2; CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]]; [_scrollView zoomToRect:zoomRect animated:YES]; } } } -(void)handleTwoFingerTap:(UITapGestureRecognizer *)gestureRecongnizer{ NSLog(@"2手指操作"); float newScale = [_scrollView zoomScale]/2; CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecongnizer locationInView:gestureRecongnizer.view]]; [_scrollView zoomToRect:zoomRect animated:YES]; } #pragma mark - 缩放大小获取方法 -(CGRect)zoomRectForScale:(CGFloat)scale withCenter:(CGPoint)center{ CGRect zoomRect; //大小 zoomRect.size.height = [_scrollView frame].size.height/scale; zoomRect.size.width = [_scrollView frame].size.width/scale; //原点 zoomRect.origin.x = center.x - zoomRect.size.width/2; zoomRect.origin.y = center.y - zoomRect.size.height/2; return zoomRect; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ @end