實現效果
目錄結構
呼叫方法
- 不帶過渡動畫,直接新增圖片瀏覽器到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地址