#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
这样,我们就完成了我们瀑布流图片编写。