#import <UIKit/UIKit.h> //这边我们会创建一个scrollView的界面,这个scrollView里面有三张图片构成,我们使用下面的枚举方式来定义这三个位置 typedef NS_ENUM(NSInteger, MRImgLocation) { MRImgLocationLeft, MRImgLocationCenter, MRImgLocationRight, }; @interface MRimgView : UIScrollView <UIScrollViewDelegate> { NSDictionary* _imgViewDic; // 这个字典里面存放了scrollView的图片,一共三个图片 } @property(nonatomic ,retain)NSMutableArray *imgSource; @property(nonatomic ,assign)NSInteger curIndex; // 当前显示图片在数据源中的下标 - (id)initWithFrame:(CGRect)frame withSourceData:(NSMutableArray *)imgSource withIndex:(NSInteger)index; // 谦让双击放大手势 - (void)requireDoubleGestureRecognizer:(UITapGestureRecognizer *)tep; @end
这边通过一个实际例子来介绍collectionViewFlow。下面是完成这个collectionViewFlow的文件:
介绍这些文件的作用:
首先第一个collectionView文件,在此文件中创建一个collectionViewFlow的瀑布流图片。
然后第二个imgViewController文件,在此文件中创建一个viewController界面,和普通的viewController界面没有什么区别。
最后第三个MRimgView文件,在此文件中创建一个scrollView界面,我们在这里可以图片的放大操作和滑动观看操作。
以上文件的链接过程:首先我们点击进入瀑布流图片界面(collectionView文件),然后我们点击一个图片的滚动视图界面(在imgViewController文件的界面上添加了一个MRimgView的滚动视图界面),就这样完成了瀑布流图片的界面。
下面来对这些文件进行一一介绍:
首先我们来介绍collectionView文件:
//**********************collectionView.h*************************//
#import <UIKit/UIKit.h> @interface collectionView : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout> //这里我们遵循了三个协议,这三个协议分别是collection的数据源,委托和自动布局协议 @property (nonatomic, strong) NSMutableArray *DataImage;//储存图片信息 @end
//**********************collectionView.m*************************//
#import "collectionView.h" #import "imgViewController.h" //我们要在这个界面上调用这个文件,在navigation中push一个imgviewController文件 @interface collectionView () { NSString *_identify; // 用于创建collectionView的cell } @end @implementation collectionView - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.title = @"图片列表"; [self _requestData]; [self _init]; self.navigationController.navigationBarHidden = YES; } -(void) _requestData { // 请求数据,储存图片 self.DataImage = [[NSMutableArray alloc] init]; for (int i = 0; i < 12; i++) { NSString *imgName = [NSString stringWithFormat:@"%d.jpg",i]; UIImage *img = [UIImage imageNamed:imgName]; [self.DataImage addObject:img]; } } -(void) _init { // 首先我们创建布局对象 UICollectionViewFlowLayout *viewLayout = [[UICollectionViewFlowLayout alloc] init]; viewLayout.itemSize = CGSizeMake(100, 150); viewLayout.minimumLineSpacing = 6;//设置每行之间的最小间距 viewLayout.minimumInteritemSpacing = 6;//设置每行中的图片的最小间距 // 设置我们的集合视图流 UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(3, 3, self.view.frame.size.width - 6, self.view.frame.size.height - 80) collectionViewLayout:viewLayout]; collectionView.dataSource = self; collectionView.delegate = self; collectionView.backgroundColor = [UIColor clearColor]; //为该cellectionView实例注册单元格 _identify = @"PhotoCell"; [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:_identify]; // 将刚刚创建的collectionView添加到界面上 [self.view addSubview:collectionView]; // 添加navigationBar的左箭头 // 自定义按钮barLeft UIButton *actionBtnlf = [UIButton buttonWithType:UIButtonTypeCustom]; [actionBtnlf setTitle:@"" forState:UIControlStateNormal]; UIImage *imgDefault = [UIImage imageNamed:@"Arrow"]; [actionBtnlf setFrame:CGRectMake(0, 0, imgDefault.size.width, imgDefault.size.height)]; [actionBtnlf setBackgroundImage:imgDefault forState:UIControlStateNormal]; [actionBtnlf addTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside]; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:actionBtnlf]; } //下面实现我们collectionView里面的delegate和datasource里面的方法 -(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { // 返回每一个section里面的试图的数量,这边我们就只有一个section return self.DataImage.count; } -(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { // 创建我们的cell,并且返回cell到的集合试图的相应位置 UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:_identify forIndexPath:indexPath]; cell.backgroundColor = [UIColor clearColor]; UIImage *image = self.DataImage[indexPath.row]; UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; imageView.contentMode = UIViewContentModeScaleToFill; imageView.frame = CGRectMake(0, 0, 100, 150); [cell.contentView addSubview:imageView]; return cell; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { // 点击相应的视图的时候,我们将调用这个方法 // 深拷贝数据 NSMutableArray *imgList = [NSMutableArray arrayWithCapacity:self.DataImage.count]; for (int i = 0; i < self.DataImage.count; i++) { UIImage *imgMod = self.DataImage[i]; [imgList addObject:imgMod]; } // 调用展示窗口,这边调用的这个方法是imgViewController借口文件中的方法 imgViewController *imgView = [[imgViewController alloc] initWithSourceData:imgList withIndex:indexPath.row]; [self.navigationController pushViewController:imgView animated:YES]; } #pragma mark -View生命周期 - (void)viewWillAppear:(BOOL)animated{ // 每当这个视图出现的时候,这个函数都会被调用 if (self.navigationController.navigationBar.translucent) { self.navigationController.navigationBar.translucent = NO; } if (self.navigationController.navigationBarHidden) { self.navigationController.navigationBarHidden = NO; } } -(void) backButtonAction { [self.navigationController popViewControllerAnimated:YES]; self.navigationController.navigationBarHidden = YES; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
下面是imgViewController文件
//**********************imgcollectionView.h*************************//
#import <UIKit/UIKit.h> @interface imgViewController : UIViewController @property (strong, nonatomic) NSMutableArray *data;//储存数据 @property (nonatomic, assign) NSInteger index;//储存点击的图片的位置 - (id)initWithSourceData:(NSMutableArray *)data withIndex:(NSInteger)index; @end
//**********************imgcollectionView.m*************************//
#import "imgViewController.h" #import "MRimgView.h" //我们在这里要加载一个MRimgview中的scrollView的文件 @interface imgViewController () @end @implementation imgViewController - (id)initWithSourceData:(NSMutableArray *)data withIndex:(NSInteger)index{ self = [super init]; if (self) { _data = data; _index = index; } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.title = @"图片列表"; //设置导航栏为半透明 self.navigationController.navigationBar.translucent = YES; // 隐藏标签栏 self.tabBarController.tabBar.hidden = YES; // 隐藏导航栏 self.navigationController.navigationBarHidden = YES; // 这里我们创建一个手势,点击View一下,此事件触发 UITapGestureRecognizer *tapGestureOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureOneAction)]; tapGestureOne.numberOfTapsRequired = 1; [self.view addGestureRecognizer:tapGestureOne]; self.automaticallyAdjustsScrollViewInsets = NO; [self.view setBackgroundColor:[UIColor blackColor]]; // 添加navigationBar的左箭头 // 自定义按钮barLeft UIButton *actionBtnlf = [UIButton buttonWithType:UIButtonTypeCustom]; [actionBtnlf setTitle:@"" forState:UIControlStateNormal]; UIImage *imgDefault = [UIImage imageNamed:@"Arrow"]; [actionBtnlf setFrame:CGRectMake(0, 0, imgDefault.size.width, imgDefault.size.height)]; [actionBtnlf setBackgroundImage:imgDefault forState:UIControlStateNormal]; [actionBtnlf addTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside]; self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:actionBtnlf]; // 为这个视图添加图片 [self creatImgShow]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void) creatImgShow { // 为视图添加图片 MRimgView *imgShowView = [[MRimgView alloc] initWithFrame:self.view.frame withSourceData:_data withIndex:_index]; //谦让双击方法事件 [imgShowView requireDoubleGestureRecognizer:[[self.view gestureRecognizers] lastObject]]; [self.view addSubview:imgShowView]; } -(void) tapGestureOneAction { // 点按视图一下,启动的action,隐藏导航栏或者出现导航栏 [UIView animateWithDuration:0.3 animations:^{ self.navigationController.navigationBarHidden = !self.navigationController.navigationBarHidden; }]; } -(void) backButtonAction { [self.navigationController popViewControllerAnimated:YES]; } /* #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
//**********************MRimgView.h*************************//
#import <UIKit/UIKit.h> //这边我们会创建一个scrollView的界面,这个scrollView里面有三张图片构成,我们使用下面的枚举方式来定义这三个位置 typedef NS_ENUM(NSInteger, MRImgLocation) { MRImgLocationLeft, MRImgLocationCenter, MRImgLocationRight, }; @interface MRimgView : UIScrollView <UIScrollViewDelegate> { NSDictionary* _imgViewDic; // 这个字典里面存放了scrollView的图片,一共三个图片 } @property(nonatomic ,retain)NSMutableArray *imgSource; @property(nonatomic ,assign)NSInteger curIndex; // 当前显示图片在数据源中的下标 - (id)initWithFrame:(CGRect)frame withSourceData:(NSMutableArray *)imgSource withIndex:(NSInteger)index; // 谦让双击放大手势 - (void)requireDoubleGestureRecognizer:(UITapGestureRecognizer *)tep; @end
//**********************MRimgView.m*************************//
#import "MRimgView.h" #define kImgViewCount 3 #define kImgZoomScaleMin 1 #define kImgZoomScaleMax 3 @implementation MRimgView { UIScrollView *_scrCenter; } - (id)initWithFrame:(CGRect)frame withSourceData:(NSMutableArray *)imgSource withIndex:(NSInteger)index { // 将我们的image传入这个类,然后将图片位置传入类中,还有这个图片的大小 self = [super initWithFrame:frame]; if (self) { // 初始化空间属性 [self initScroller]; // 设置数据源的操作 [self setImgSource:imgSource]; // 设置图片下标 [self setCurIndex:index]; } return self; } -(void) initScroller { // 初始化self的scrollerView控件属性 self.delegate = self; self.showsHorizontalScrollIndicator = NO; self.showsVerticalScrollIndicator = NO; self.pagingEnabled = YES; self.backgroundColor = [UIColor clearColor]; // 构建展示组 [self initImgViewDic]; } - (void)setImgSource:(NSMutableArray *)imgSource { // 这边我们进行数据的插入操作 if (_imgSource != imgSource) { _imgSource = imgSource; // 设置展示板尺寸 [self setConSize]; } } // 展示板尺寸设置 - (void)setConSize{ CGSize size = self.frame.size; //设置内容视图的大小--单页填充、横向划动 self.contentSize = CGSizeMake(size.width * kImgViewCount, size.height); // 设置显示页 这句话的作用是设置了滚动视图现实在屏幕上的区域,距离坐标原点的向量是(320,0),因此把scrCenter显示在屏幕上 [self setContentOffset:CGPointMake(size.width, 0)]; } // 初始化展示板组 -(void) initImgViewDic { UIImageView *imgLeft = [self creatImageView]; UIImageView *imgCenter = [self creatImageView]; UIImageView *imgRight = [self creatImageView]; _imgViewDic = [[NSDictionary alloc] initWithObjectsAndKeys: imgLeft, @"imgLeft", imgCenter, @"imgCenter", imgRight, @"imgRight", nil]; // 创建滚动视图 UIScrollView *scrLeft = [self scrollViewWithPosition:MRImgLocationLeft withImgView:imgLeft]; _scrCenter = [self scrollViewWithPosition:MRImgLocationCenter withImgView:imgCenter]; UIScrollView *scrRight = [self scrollViewWithPosition:MRImgLocationRight withImgView:imgRight]; //设置放大缩小极限倍数 _scrCenter.maximumZoomScale = kImgZoomScaleMax; _scrCenter.minimumZoomScale = kImgZoomScaleMin; _scrCenter.delegate = self; // 添加双击手势 UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapClick:)]; doubleTap.numberOfTapsRequired = 2; [self addGestureRecognizer:doubleTap]; // 放入展示板 [self addSubview:scrLeft]; [self addSubview:_scrCenter]; [self addSubview:scrRight]; } // 通过创建展示板 - (UIImageView *)creatImageView{ CGFloat width = self.frame.size.width; CGFloat height = self.frame.size.height; UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, height)]; return imgView; } - (UIScrollView *)scrollViewWithPosition:(MRImgLocation)imgLocation withImgView:(UIImageView *)imgView { // 创建滚动视图 CGFloat width = self.frame.size.width; CGFloat height= self.frame.size.height; UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(width * imgLocation, 0, width, height)]; scrollView.backgroundColor = [UIColor blackColor]; [scrollView addSubview:imgView]; // 设置图片显示样式 imgView.contentMode = UIViewContentModeScaleAspectFit; return scrollView; } - (void)setCurIndex:(NSInteger)curIndex { // 设置图片内容 //第2、3个if是为了设置循环滚动 if (_imgSource.count > curIndex && curIndex >= 0) { _curIndex = curIndex; } else if (curIndex == -1){ _curIndex = _imgSource.count - 1; } else if (curIndex == _imgSource.count){ _curIndex = 0; } if (_imgSource.count) {[self setAllImgVContentFromImage:[self imgListFromIndex:_curIndex]];} } // 载入一组图片 - (void)setAllImgVContentFromImage:(NSArray *)imgList{ // 将所有imgList中的数据载入展示板 UIImageView *vLift = [_imgViewDic valueForKey:@"imgLeft"]; UIImageView *vCenter = [_imgViewDic valueForKey:@"imgCenter"]; UIImageView *vRight = [_imgViewDic valueForKey:@"imgRight"]; [vLift setImage:imgList[MRImgLocationLeft]]; [vCenter setImage:imgList[MRImgLocationCenter]]; [vRight setImage:imgList[MRImgLocationRight]]; } // 根据当前索引赋值图片 该方法返回一个存有左中右3个image的数组 - (NSArray *)imgListFromIndex:(NSInteger)curIndex{ long sCount = _imgSource.count; NSArray *imgList; UIImage *imgL; UIImage *imgC; UIImage *imgR; if (sCount) { // 首位 if (curIndex == 0) { imgL = [_imgSource lastObject]; imgC = _imgSource[curIndex]; long nextIndex = curIndex == sCount - 1 ? curIndex : curIndex + 1; imgR = _imgSource[nextIndex]; // 末位 } else if (curIndex == sCount - 1){ long lastIndex = curIndex == 0 ? curIndex : curIndex - 1; imgL = _imgSource[lastIndex] ; imgC = [_imgSource lastObject]; imgR = _imgSource[0]; // 中间 } else { imgL = _imgSource[curIndex - 1]; imgC = _imgSource[curIndex]; imgR = _imgSource[curIndex + 1]; } imgList = [[NSArray alloc] initWithObjects:imgL, imgC, imgR, nil]; } return imgList; } - (void)doubleTapClick:(UITapGestureRecognizer *)tap { // 在这里实现点按两下的action操作 // 判断当前放大的比例 if (_scrCenter.zoomScale > kImgZoomScaleMin) { [_scrCenter setZoomScale:kImgZoomScaleMin animated:YES]; } else [_scrCenter setZoomScale:kImgZoomScaleMax animated:YES]; } - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{ UIImageView *vCenter = [_imgViewDic valueForKey:@"imgCenter"]; return vCenter; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { if (self == scrollView) { CGFloat width = self.frame.size.width; int currentOffset = scrollView.contentOffset.x/width - 1; [self setCurIndex:_curIndex + currentOffset]; // 返回三个视图中的中间位置 [scrollView setContentOffset:CGPointMake(width, 0) animated:NO]; [_scrCenter setZoomScale:kImgZoomScaleMin]; } } // 谦让双击放大手势 - (void)requireDoubleGestureRecognizer:(UITapGestureRecognizer *)tep{ [tep requireGestureRecognizerToFail:[[self gestureRecognizers] lastObject]]; } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ @end
这样,我们就完成了我们瀑布流图片编写。