實現效果
PhotoBrowser.gif
目錄結構
image.png
調用方法
- 不帶過渡動畫,直接添加圖片瀏覽器到window上
/**
* 查看本地圖片(不帶過渡動畫,直接加到window上)
* urls 大圖的url數組
*/
+ (PDPhotoBrowser *)photoWithImages:(NSArray *)images;
/**
* 查看網絡圖片(不帶過渡動畫,直接加到window上)
* urls 大圖的url數組
*/
+ (PDPhotoBrowser *)photoWithUrls:(NSArray *)urls;
- 附帶微信圖片瀏覽器一樣的過渡動畫
/*
* 查看本地圖片(帶過渡動畫)
* 用image數組快速創建圖片瀏覽器
* currentIndex 當前操作的下標
* animateView 獲取縮放返回的imageView的回調block
*/
+ (PDPhotoBrowser *)photoWithImages:(NSArray *)images currentIndex:(NSInteger)currentIndex animateView:(PDAnimateView)animateView;
/*
* 查看網絡圖片(帶過渡動畫)
* urls 大圖的url數組
* currentIndex 當前操作的下標
* animateView 獲取縮放返回的imageView的回調block
*/
+ (PDPhotoBrowser *)photoWithUrls:(NSArray *)urls currentIndex:(NSInteger)currentIndex animateView:(PDAnimateView)animateView;
實現原理
- 利用UICollectionView實現圖片瀏覽
- UICollectionView的Cell底部是一個UIScrollView,在_scrollView上添加UIImageView用來展示圖片,添加自定義的progressView用來顯示加載進度
- UICollectionView的Cell添加單擊手勢退出圖片瀏覽器,雙擊手勢放大圖片,長按手勢彈出操作框
- 根據圖片和屏幕比例關系,調整最大和最小伸縮比例,和換算長圖的寬高
- 如果圖片寬度比屏幕寬度小,將圖片設置為屏幕等寬,根據比例換算高度
- 如果圖片是橫向長圖,調整imageView大小為圖片實際尺寸將_scrollView的contentSize寬度設置為圖片實際寬度,調整imageView的center,設置_scrollView的contentSize確保橫向滾動
- 如果圖片是豎向長圖,調整imageView大小為圖片實際尺寸將_scrollView的contentSize高度設置為圖片實際高度,調整imageView的center,設置_scrollView的contentSize確保眾向滾動
- 設置_scrollView的最大最小縮放比例
/**
* 根據圖片和屏幕比例關系,調整最大和最小伸縮比例
*/
- (void)setMaxAndMinZoomScales
{
// self.photoImageView的初始位置
UIImage *image = self.imageView.image;
if (image == nil || image.size.height == 0) {
return;
}
CGFloat imageWidthHeightRatio = image.size.width / image.size.height;
CGRect imageViewFrame = CGRectZero;
imageViewFrame.size.width = _scrollView.frame.size.width;
imageViewFrame.size.height = _scrollView.frame.size.width / imageWidthHeightRatio;
imageViewFrame.origin.x = 0;
//垂直方向長圖
if (imageViewFrame.size.height > _scrollView.frame.size.height) {
imageViewFrame.origin.y = 0;
_scrollView.scrollEnabled = YES;
} else {
imageViewFrame.origin.y = (_scrollView.frame.size.height - imageViewFrame.size.height ) * 0.5;
_scrollView.scrollEnabled = NO;
}
self.imageView.frame = imageViewFrame;
_scrollView.maximumZoomScale = MAX(_scrollView.frame.size.height / self.imageView.bounds.size.height, 3.0);
_scrollView.minimumZoomScale = 1.0;
_scrollView.zoomScale = 1.0;
_scrollView.contentSize = CGSizeMake(imageViewFrame.size.width, MAX(imageViewFrame.size.height, _scrollView.frame.size.height));
}
- 添加打開圖片瀏覽器和退出時的過渡動畫
- 先獲取點擊的view,將view從原父容器坐標轉換到圖片瀏覽器的坐標,記為開始坐標
- 換算view動畫完成的坐標,記為目的坐標
- 創建一個臨時的動畫view,來完成從開始坐標到目的坐標的動畫
- 退出圖片瀏覽器的動畫反之
/**
* 開始打開相冊的過渡動畫
*/
- (void)beginShowTransfromAnimation
{
//獲取到用戶點擊的那個UIImageView對象,進行坐標轉化
CGRect startRect;
if (self.animateView) {
_animateImageView = self.animateView(_currentIndex);
}
startRect = [self.animateImageView.superview convertRect:self.animateImageView.frame toView:self];
//利用零時tempImageView完成過度的形變動畫
UIImageView *tempImageView = [[UIImageView alloc] init];
UIImage *image = self.animateImageView.image;
if (!image) {
image = [UIImage imageNamed:@"pb_placeHolder"];
}
tempImageView.image = image;
tempImageView.frame = startRect;
[self addSubview:tempImageView];
CGRect targetRect; // 目標frame
CGFloat imageWidthHeightRatio = image.size.width / image.size.height;
CGFloat width = self.bounds.size.width;
CGFloat height = self.bounds.size.width / imageWidthHeightRatio;
CGFloat x = 0;
CGFloat y;
if (height > self.bounds.size.height) {
y = 0;
} else {
y = (self.bounds.size.height - height ) * 0.5;
}
targetRect = CGRectMake(x, y, width, height);
_collectionView.hidden = YES;
self.alpha = 1.0;
// 動畫修改圖片視圖的frame,居中同時放大
[UIView animateWithDuration:0.3 animations:^{
tempImageView.frame = targetRect;
} completion:^(BOOL finished) {
[tempImageView removeFromSuperview];
_collectionView.hidden = NO;
}];
}
PDPhotoBrowser
是基于collectionView實現的圖片瀏覽器,詳情請點擊Demo地址