iOS学习笔记 UICollectionView入门
2016-09-22 13:02
92 查看
一、UICollectionView介绍
UICollectionView和
UICollectionViewController类是iOS6新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于
UITableView和
UITableViewController类,但也有所不同。
UICollectionView可以实现如下效果,也是一个常用的控件:
二、UICollectiomView使用
UICollectionView的创建和
UITableView的创建有所不同:
UITableView的创建只需要设置
frame即可使用
UICollectionView除了需要
frame,还需要一个布局参数
-(id)initWithFrame:(CGRect)frame /* 尺寸 */ collectionViewLayout:(UICollectionViewLayout *)layout;/* 布局参数 */
UITableView可以不需要注册Cell视图类,手动创建Cell视图类
UICollectionView必须注册视图类,才能显示,不需要手动创建
UICollectionView的布局参数:
是一个
UICollectionViewLayout类的对象,
但我们一般使用它的子类
UICollectionViewFlowLayout
设置布局对象的滚动方向属性
scrollDirection:
typedef NS_ENUM(NSInteger, UICollectionViewScrollDirection) { UICollectionViewScrollDirectionVertical, /*垂直滚动*/ UICollectionViewScrollDirectionHorizontal /* 水平滚动 */ };
垂直滚动,表示Cell方块布局是从左往右,从上到下排列的布局
水平滚动,表示Cell方块布局是从上往下,从左到右排列的布局
和
UITableView不同,
UICollectionView只能在这里设置顶部视图和底部视图的大小
设置为垂直滚动时,顶部和底部视图的宽度为
UICollectionView的宽度,无法设置
设置为水平滚动时,顶部和底部视图的高度为
UICollectionView的高度,无法设置
UICollectionView的常用对象方法
/* 向容器视图注册Cell方块视图,有2种方式,一种是类名注册,一种是Xib注册 */ - (void)registerClass:(Class)cellClass /* 视图类 */ forCellWithReuseIdentifier:(NSString *)identifier;/* 绑定标识 */ - (void)registerNib:(UINib *)nib /* Xib */ forCellWithReuseIdentifier:(NSString *)identifier;/* 绑定标识 */ /* 从缓存池中取出Cell方块视图对象,如果缓存池没有,自动调用alloc/initWithFrame创建 */ - (UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath; /* kind参数设置 */ NSString *const UICollectionElementKindSectionHeader;/* 顶部视图用这个 */ NSString *const UICollectionElementKindSectionFooter;/* 底部视图用这个 */ /* 向容器视图注册顶部视图或者底部视图,有2种方式,一种是类名注册,一种是Xib注册 */ - (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)kind /* 参考上面 */ withReuseIdentifier:(NSString *)identifier;/* 绑定标识 */ - (void)registerNib:(UINib *)nib forSupplementaryViewOfKind:(NSString *)kind /* 参考上面 */ withReuseIdentifier:(NSString *)identifier;/* 绑定标识 */ /* 从缓存池中取出顶部视图对象或者底部视图对象,如果缓存池没有,自动调用alloc/initWithFrame创建 */ - (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
UICollectionView的数据源方法
@required /* 设置容器视图各个组都有多少个Cell方块 */ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section; /* 设置Cell方块视图,类似于UITableViewCell的设置 */ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath; @optional /* 容器视图有多少个组,默认返回1 */ - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView; /* 设置顶部视图和底部视图,通过kind参数分辨是设置顶部还是底部 */ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
UICollectionViewDelegate的常用方法
/* 选中Cell方块时调用 */ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath; /* 取消选中Cell方块时调用 */ - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
我们使用更多的是
UICollectionViewDelegate子协议
UICollectionViewDelegateFlowLayout
该协议不仅包含父协议所有方法,还可以进行一些布局设置
UICollectionViewDelegateFlowLayout的常用布局方法
/* 设置每个方块的尺寸大小 */ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath; /* 设置方块视图和边界的上下左右间距 */ - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
下面是我自定义的Cell视图类、顶部视图类、底部视图类,目录结构如下:
方块视图LTCollectionViewCell.h
#import <UIKit/UIKit.h> @interface LTCollectionViewCell : UICollectionViewCell @property (strong, nonatomic) UILabel *textLabel; /* 方块视图的缓存池标示 */ + (NSString *)cellIdentifier; /* 获取方块视图对象 */ + (instancetype)cellWithCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath; @end
方块视图LTCollectionViewCell.m
#import "LTCollectionViewCell.h" @implementation LTCollectionViewCell /* 方块视图的缓存池标示 */ + (NSString *)cellIdentifier{ static NSString *cellIdentifier = @"CollectionViewCellIdentifier"; return cellIdentifier; } /* 获取方块视图对象 */ + (instancetype)cellWithCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath { //从缓存池中寻找方块视图对象,如果没有,该方法自动调用alloc/initWithFrame创建一个新的方块视图返回 LTCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[LTCollectionViewCell cellIdentifier] forIndexPath:indexPath]; return cell; } /* 注册了方块视图后,当缓存池中没有底部视图的对象时候,自动调用alloc/initWithFrame创建 */ - (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { //创建label UILabel *textLabel = [[UILabel alloc] init]; //设置label尺寸 CGFloat x = 5; CGFloat y = 5; CGFloat width = frame.size.width - 10; CGFloat height = frame.size.height - 10; textLabel.frame = CGRectMake(x, y, width, height); //设置label属性 textLabel.numberOfLines = 0; textLabel.textAlignment = NSTextAlignmentCenter; textLabel.font = [UIFont systemFontOfSize:15]; //添加到父控件 [self.contentView addSubview:textLabel]; self.textLabel = textLabel; } return self; } @end
顶部视图LTCollectionHeaderView.h
#import <UIKit/UIKit.h> @interface LTCollectionHeaderView : UICollectionReusableView @property (strong, nonatomic) UILabel *textLabel; /* 顶部视图的缓存池标示 */ + (NSString *)headerViewIdentifier; /* 获取顶部视图对象 */ + (instancetype)headerViewWithCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath; @end
顶部视图LTCollectionHeaderView.m
#import "LTCollectionHeaderView.h" @implementation LTCollectionHeaderView /* 顶部视图的缓存池标示 */ + (NSString *)headerViewIdentifier{ static NSString *headerIdentifier = @"headerViewIdentifier"; return headerIdentifier; } /* 获取顶部视图对象 */ + (instancetype)headerViewWithCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath { //从缓存池中寻找顶部视图对象,如果没有,该方法自动调用alloc/initWithFrame创建一个新的顶部视图返回 LTCollectionHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:[LTCollectionHeaderView headerViewIdentifier] forIndexPath:indexPath]; return headerView; } /* 注册了顶部视图后,当缓存池中没有顶部视图的对象时候,自动调用alloc/initWithFrame创建 */ - (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { //创建label UILabel *textLabel = [[UILabel alloc] init]; //设置label尺寸 CGFloat x = 5; CGFloat y = 5; CGFloat width = frame.size.width - 10; CGFloat height = frame.size.height - 10; textLabel.frame = CGRectMake(x, y, width, height); //设置label属性 textLabel.numberOfLines = 0; textLabel.textAlignment = NSTextAlignmentCenter; //添加到父控件 [self addSubview:textLabel]; self.textLabel = textLabel; } return self; } @end
底部视图LTCollectionFooterView.h
#import <UIKit/UIKit.h> @interface LTCollectionFooterView : UICollectionReusableView @property (strong, nonatomic) UILabel *textLabel; /* 底部视图的缓存池标示 */ + (NSString *)footerViewIdentifier; /* 获取底部视图对象 */ + (instancetype)footerViewWithCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath; @end
底部视图LTCollectionFooterView.m
#import "LTCollectionFooterView.h" @implementation LTCollectionFooterView /* 底部视图的缓存池标示 */ + (NSString *)footerViewIdentifier{ static NSString *footerIdentifier = @"footerViewIdentifier"; return footerIdentifier; } /* 获取底部视图对象 */ + (instancetype)footerViewWithCollectionView:(UICollectionView *)collectionView forIndexPath:(NSIndexPath *)indexPath { //从缓存池中寻找底部视图对象,如果没有,该方法自动调用alloc/initWithFrame创建一个新的底部视图返回 LTCollectionFooterView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:[LTCollectionFooterView footerViewIdentifier] forIndexPath:indexPath]; return footerView; } /* 注册了底部视图后,当缓存池中没有底部视图的对象时候,自动调用alloc/initWithFrame创建 */ - (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { //创建label UILabel *textLabel = [[UILabel alloc] init]; //设置label尺寸 CGFloat x = 5; CGFloat y = 5; CGFloat width = frame.size.width - 10; CGFloat height = frame.size.height - 10; textLabel.frame = CGRectMake(x, y, width, height); //设置label属性 textLabel.numberOfLines = 0; textLabel.textAlignment = NSTextAlignmentCenter; //添加到父控件 [self addSubview:textLabel]; self.textLabel = textLabel; } return self; } @end
下面是使用实例:
1. 视图控制器属性和相关方法
#import "ViewController.h" #import "LTCollectionViewCell.h" #import "LTCollectionHeaderView.h" #import "LTCollectionFooterView.h" @interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> @property (strong, nonatomic) UICollectionView *collectionView;/*< 容器视图 */ @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化容器视图 [self initCollectionView]; }
2. 初始化容器视图
/* 初始化容器视图 */ - (void)initCollectionView { CGFloat x = 0; CGFloat y = 20; CGFloat width = self.view.frame.size.width; CGFloat height = self.view.frame.size.height - 20; //创建布局对象 UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; //设置滚动方向为垂直滚动,说明方块是从左上到右下的布局排列方式 layout.scrollDirection = UICollectionViewScrollDirectionVertical; //设置顶部视图和底部视图的大小,当滚动方向为垂直时,设置宽度无效,当滚动方向为水平时,设置高度无效 layout.headerReferenceSize = CGSizeMake(100, 40); layout.footerReferenceSize = CGSizeMake(100, 40); //创建容器视图 CGRect frame = CGRectMake(x, y, width, height); UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:layout]; collectionView.delegate = self;//设置代理 collectionView.dataSource = self;//设置数据源 collectionView.backgroundColor = [UIColor whiteColor];//设置背景,默认为黑色 //添加到主视图 [self.view addSubview:collectionView]; self.collectionView = collectionView; //注册容器视图中显示的方块视图 [collectionView registerClass:[LTCollectionViewCell class] forCellWithReuseIdentifier:[LTCollectionViewCell cellIdentifier]]; //注册容器视图中显示的顶部视图 [collectionView registerClass:[LTCollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:[LTCollectionHeaderView headerViewIdentifier]]; //注册容器视图中显示的底部视图 [collectionView registerClass:[LTCollectionFooterView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:[LTCollectionFooterView footerViewIdentifier]]; }
3. UICollectionViewDataSource数据源方法
#pragma mark - UICollectionViewDataSource /* 设置容器中有多少个组 */ - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{ return 10; } /* 设置每个组有多少个方块 */ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return 20; } /* 设置方块的视图 */ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { //获取cell视图,内部通过去缓存池中取,如果缓存池中没有,就自动创建一个新的cell LTCollectionViewCell *cell = [LTCollectionViewCell cellWithCollectionView:collectionView forIndexPath:indexPath]; //设置cell属性 cell.contentView.backgroundColor = [UIColor redColor]; cell.textLabel.text = [NSString stringWithFormat:@"Cell %2ld",indexPath.row]; return cell; } /* 设置顶部视图和底部视图 */ - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath { if ( [kind isEqualToString:UICollectionElementKindSectionHeader] ) {//顶部视图 //获取顶部视图 LTCollectionHeaderView *headerView = [LTCollectionHeaderView headerViewWithCollectionView:collectionView forIndexPath:indexPath]; //设置顶部视图属性 headerView.backgroundColor = [UIColor orangeColor]; headerView.textLabel.text = [NSString stringWithFormat:@"-Header-%ld-",indexPath.section]; return headerView; } else if( [kind isEqualToString:UICollectionElementKindSectionFooter] ) {//底部视图 //获取底部视图 LTCollectionFooterView *footerView = [LTCollectionFooterView footerViewWithCollectionView:collectionView forIndexPath:indexPath]; //设置底部视图属性 footerView.backgroundColor = [UIColor greenColor]; footerView.textLabel.text = [NSString stringWithFormat:@"-Footer-%ld-",indexPath.section]; return footerView; } return nil; }
4. UICollectionViewDelegateFlowLayout布局代理方法
#pragma mark - UICollectionViewDelegateFlowLayout /* 设置各个方块的大小尺寸 */ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { CGFloat width = 50; CGFloat height = 50; return CGSizeMake(width, height); } /* 设置每一组的上下左右间距 */ - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { return UIEdgeInsetsMake(10, 10, 10, 10); }
5. 父协议UICollectionViewDelegate的代理方法
#pragma mark - UICollectionViewDelegate /* 方块被选中会调用 */ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"点击选择了第%ld组第%ld个方块",indexPath.section,indexPath.row); } /* 方块取消选中会调用 */ - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"取消选择第%ld组第%ld个方块",indexPath.section,indexPath.row); } @end
效果图如下,左边为垂直滚动效果,右边为水平滚动效果
如果修改下布局代理方法的上下左右边界距离:
/* 设置每一组的上下左右间距 */ - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { return UIEdgeInsetsMake(0, 0, 0, 0); }
相关文章推荐
- iOS SDK 4.3 学习笔记 iPhone101 (01)
- CCNA第二天学习笔记之Cisco系统IOS
- IOS 学习笔记
- 关于ios新浪sdk学习笔记
- [iOS]学习笔记3(动态性)
- iOS UIResponder 学习笔记
- [原][学习笔记][2011.11.14] ios的试图, 控件的总结.
- Effective C++学习笔记:条款2:尽量用iostram而不用stdio.h
- IOS 学习笔记(四)ios理解
- [原][学习笔记][2011.11.14] 实现ios 主要的几个控件demo
- ccna学习笔记之七:删除ios
- iOS SDK 4.3 学习笔记 iPhone101 (04)
- iOS SDK 4.3 学习笔记 iPhone101 (03)
- iOS SDK 4.3 学习笔记 iPhone101 (02)
- IOS 学习笔记(二)object-c理解
- 新浪微博iOS版SDK“宝玉XP”框架学习笔记
- ios学习笔记之四种数据持久化方法
- iOS SDK 4.3 ( Xcode 4 )学习笔记 iPhone101 (05)
- 新浪微博iOS版SDK“宝玉XP”框架研究的 学习笔记
- iOS UIResponder 学习笔记