主要實現的功能
1.封裝一個imageview imageview上顯示九個縮略圖
2.點擊圖片實現放大效果顯示高清圖片
3.當查看大圖的時候可以滑動查看其它圖
4.當點擊圖片的時候圖片縮小回歸到原來的九宮格中
實現方法看代碼
用了SDWebImage
和UIView+UIViewController
#import <UIKit/UIKit.h>
#import "WBImageViewItem.h"
@interface WBImageView : UIView
@property(nonatomic,copy)NSArray *imageList;//圖片的url數組
@property(nonatomic,assign)NSInteger subImageViewSpace;//設置圖片大小
@property(nonatomic,assign)NSInteger subImageViewInset;//設置圖片空隙大小
@property(nonatomic,copy)NSMutableArray *items;//圖片的item數組
@end
#import "WBImageView.h"
#import "UIImageView+WebCache.h"
#define ZQItemWidth self.subImageViewSpace
#define ZQItemHeight self.subImageViewSpace
#define ZQSpace self.subImageViewInset
@implementation WBImageView
//這個方法是解決 不能同時使用set方法和get方法的
@synthesize subImageViewSpace = _subImageViewSpace;
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (NSInteger)subImageViewInset{
if (_subImageViewInset == 0) {
return 5;
}
return _subImageViewInset;
}
- (NSInteger)subImageViewSpace{
if (_subImageViewSpace==0) {
return 80;
}
return _subImageViewSpace;
}
- (void)setSubImageViewSpace:(NSInteger)subImageViewSpace{
_subImageViewSpace=subImageViewSpace;
}
- (void)setImageList:(NSArray *)imageList{
_imageList=imageList;
#pragma mark -- 根據傳入的數據 計算視圖的寬高
CGFloat width=ZQItemWidth*3+ZQSpace*2;
CGFloat height=((_imageList.count-1)/3+1)*ZQItemHeight+ZQSpace*((_imageList.count-1)/3);
self.frame=CGRectMake(self.frame.origin.x, self.frame.origin.y, width, height);
#pragma mark --創建UIImageView顯示圖片
//這裏將所有創建愛你出來的圖片視圖存儲起來 當我們想要放大的時候會用到
_items=[[NSMutableArray alloc]init];
for (int index=0; index<_imageList.count; index++) {
//初始化九宮格視圖內的imagView
WBImageViewItem *item=[[WBImageViewItem alloc]initWithFrame:[self getItemFrameForSupview:index]];
item.imageList=_imageList;
//設置一個標記 讓外部知道現在是第幾個item 用來計算座標
item.index=index;
[item sd_setImageWithURL:_imageList[index]];
[_items addObject:item];
#pragma mark -- 將item的frame存儲起來 當我們點擊大圖縮小的時候使用
item.originFrame=item.frame;
[self addSubview:item];
}
}
#pragma mark -- 根據item加載的圖片在數組的位置 計算item在父視圖上的frame屬性
- (CGRect)getItemFrameForSupview:(int)index{
CGFloat x=index%3*(ZQSpace+ZQItemWidth);
CGFloat y=index/3*(ZQSpace+ZQItemHeight);
return CGRectMake(x, y, ZQItemWidth, ZQItemHeight);
}
@end
#import <UIKit/UIKit.h>
@interface WBImageViewItem : UIImageView
@property(nonatomic,copy)NSArray *imageList;
@property(nonatomic,assign)NSInteger index;//用於scrollView計算contentSize
@property(nonatomic,assign)CGRect originFrame;//原始frame,做完放大動畫後恢復原狀態
@end
#import "WBImageViewItem.h"
#import "UIView+UIViewController.h"
#import "WBImageViewController.h"
@implementation WBImageViewItem
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
//開啓imageView的響應點擊事件
self.userInteractionEnabled=YES;
//設置imagView的顯示模式 該模式爲不對圖片進行拉伸 原比例放大
self.contentMode=UIViewContentModeScaleAspectFit;
//添加點擊事件 當點擊的時候執行放大動畫
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:self
action:@selector(tapAction:)];
[self addGestureRecognizer:tap];
}
return self;
}
- (void)tapAction:(UITapGestureRecognizer *)tap{
//當點擊的時候彈出控制器
WBImageViewController *viewC=[[WBImageViewController alloc]init];
//設置控制器的數據 當我們要在scroll上顯示數據的時候使用
viewC.imageList=_imageList;
viewC.currentItem=self;
//記錄 self.superview 是WBImageView
viewC.itemOriginSuperView=(WBImageView *)self.superview;
//彈出視圖控制器
[self.viewController presentViewController:viewC animated:NO completion:nil];
}
@end
#import <UIKit/UIKit.h>
#import "WBImageViewItem.h"
#import "WBImageView.h"
@interface WBImageViewController : UIViewController
@property(nonatomic,copy)NSArray *imageList;
@property(nonatomic,strong)WBImageViewItem *currentItem;//記錄當前的item
@property(nonatomic,strong)WBImageView *itemOriginSuperView;//記錄原始的itme的父視圖 用以查找放大前的座標
@end
#import "WBImageViewController.h"
#import "UIImageView+WebCache.h"
@interface WBImageViewController ()<UIScrollViewDelegate>
{
UIScrollView *_scrollView;//用於顯示大圖
}
@end
@implementation WBImageViewController
#pragma mark -- 執行放大的動畫
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
//改變點擊的item的origin屬性 當我們點擊item的時候 我們需要這個圖片的動畫的起點是我們點擊圖片的位置
//轉換item所在位置的座標 這樣看來就是縮略圖的位置沒有變化 但是他的父視圖換了一下
//下面的方法 有三個參數 一個返回值 三個參數分別是 原有的frame所在的父視圖 原有的frame 和目的視圖 返回值是目的frame
self.currentItem.frame=[self.currentItem.superview convertRect:self.currentItem.frame toView:self.view];
//將點擊的item拿到視圖控制器上
[self.view addSubview:self.currentItem];
[UIView animateWithDuration:2 animations:^{
self.currentItem.frame=self.view.frame;
} completion:^(BOOL finished) {
_scrollView.hidden=NO;//顯示高清圖片
//恢復item的frame
self.currentItem.frame=self.currentItem.originFrame;
//將item放回原始的父視圖上 我們在這裏移動的是縮略圖 在這裏肯能有些不好理解
//爲什麼不在當點擊縮小的時候纔去縮小?
//因爲當我們在彈出的視圖控制器種可能會滾動換一個圖片 這時候 在這裏拿到的圖片 和縮小回去的圖片就不是一個
//具體怎麼實現滾動後如何縮小看tapAction
[self.itemOriginSuperView addSubview:self.currentItem];
}];
}
- (void)viewDidLoad {
[super viewDidLoad];
//彈出大圖瀏覽的視圖控制器
//創建ScrollView實現圖片瀏覽
_scrollView=[[UIScrollView alloc]initWithFrame:self.view.bounds];
_scrollView.contentSize=CGSizeMake(self.view.frame.size.width*_imageList.count, self.view.frame.size.height);
for (int i=0; i<_imageList.count; i++) {
UIImageView *imageVie=[[UIImageView alloc]initWithFrame:CGRectMake(self.view.frame.size.width*i, 0, self.view.frame.size.width, self.view.frame.size.height)];
[_scrollView addSubview:imageVie];
#pragma mark -- 添加單擊手勢 實現恢復動畫
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
imageVie.userInteractionEnabled=YES;
[imageVie addGestureRecognizer:tap];
#pragma mark -- 設置圖片的展示形式 這個方法是設置圖片不拉伸 展現原始比例
imageVie.contentMode=UIViewContentModeScaleAspectFit;
//thumbnail縮略圖 small 小圖 large 大圖
NSString *largeURL=[_imageList[i]stringByReplacingOccurrencesOfString:@"thumbnail" withString:@"large"];
[imageVie sd_setImageWithURL:[NSURL URLWithString:largeURL]];
}
[_scrollView setPagingEnabled:YES];
_scrollView.delegate=self;
_scrollView.hidden=YES;//默認隱藏 當放大動畫結束後顯示
[_scrollView scrollRectToVisible:CGRectMake(self.currentItem.index *self.view.frame.size.width,0,self.view.frame.size.width,self.view.frame.size.height)
animated:NO];
[self.view addSubview:_scrollView];
}
#pragma mark -- 當點擊屏幕的時候縮小
- (void)tapAction:(UITapGestureRecognizer *)tap{
//當點擊的時候我們需要知道我們點擊的是哪個item
//這個currentItem在哪去設置呢?
//最開始的時候我們是有一個的 當我們滾動的時候還需要去設置一下
//保存curreItem當 self dismiss self將被釋放 先將他保存一下
WBImageViewItem *item=self.currentItem;
//這裏當我們做縮小動畫的時候 需要回到WBImageView中實現 縮小的過程 會出現正在縮小的圖片在小圖片的下面 可以註釋這句話看效果
[item.superview bringSubviewToFront:item];
//轉換座標 從當前視圖 轉化爲要顯示視圖上的座標
CGPoint point=[self.view convertPoint:CGPointZero
toView:self.itemOriginSuperView];
item.frame=CGRectMake(point.x,point.y,self.view.frame.size.width,self.view.frame.size.height);
[self dismissViewControllerAnimated:NO completion:^{
[UIView animateWithDuration:2 animations:^{
item.frame=item.originFrame;
}];
}];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//計算當前位置
NSInteger currentIndex=scrollView.contentOffset.x/self.view.frame.size.width;
//改變當前的item當圖片返回的時候使用
self.currentItem=self.itemOriginSuperView.items[currentIndex];
}
@end