1. UICollectionView 和 UITableView 的UI区别
UICollectionView默认没有表头, UITableView: 有表头和表尾;
UICollectionView的区里面是项Item, UITableView:区里面是单元格Cell
UICollectionView布局使用UICollectionViewLayOut的子类(UICollectionViewFlowLayOut 流式布局:流式布局的特点就是会自动根据屏幕的宽度适当的显示列数,如果屏幕款显示的列数可能就多,例如iphone 6s Plus, 如果屏幕相对较窄,显示的列数则较少,例如 iphone 4s)
UICollectionView和UITableView都是分区(段)的
影响UICollectionView显示的列数的因素有:
①:UICollectionView宽度,宽度越大,显示列数越多;
②:Item宽度, 每一项的宽度越窄,则显示的列数越多;
③: 每个Item的列间隙,列间距越窄,显示的越多;
影响UICollectionView 行数的因素:
UICollectionView 的行数是不能显式指定的,行数是系统自动计算出来的,行数的计算因素有: Item 宽度 和 列间隙 共同决定
UICollectionView 滚动方向与Item的排列方向
滚动方向不同,每个Item的出现顺序也不同;
滚动方向如果是垂直方向,那么Item是横着排列,先排第一行,如果一行排列不完,就继续排第二行;
滚动方向如果是水平方向,那么Item是垂直排列,先排第一列,如果一列排列不完,就继续排序第二列,如果有多个分区,每个分区的第一项肯定再第一行,而不会排在排在上一个分区的尾部,而是另起一列
UICollectionViewScrollDirectionVertical(垂直方向) UICollectionViewScrollDirectionHorizontal (水平方向)
由图可见,滚动方向 垂直和水平 第二个Item出现的位置不同
滚动方向和排列方向 成垂直关系, 如下图解:
2.UICollectionView 知识点
UICollectionViewFlowLayout:Item 的流式布局
- @interface UICollectionViewFlowLayout : UICollectionViewLayout
-
- @property (nonatomic) CGFloat minimumLineSpacing;
- @property (nonatomic) CGFloat minimumInteritemSpacing;
- @property (nonatomic) CGSize itemSize;
- @property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0);
- @property (nonatomic) UICollectionViewScrollDirection scrollDirection;
- @property (nonatomic) CGSize headerReferenceSize;
- @property (nonatomic) CGSize footerReferenceSize;
-
- @property (nonatomic) UIEdgeInsets sectionInset;
-
- @property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
- @property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
-
- @end
UICollectionView
- @interface UICollectionView : UIScrollView
-
- - (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
-
- @end
UICollectionViewFlowLayout 的属性设置
流式布局的Item设置:
①:使用UICollectionViewFlowLayout的属性进行设置(此种方法是对所有Item都统一设置)
②:使用UICollectionViewDelegateFlowLayout协议进行设置(此种方法即可以统一设置又可以对某些Item进行特殊设置)
UICollectionViewDelegateFlowLayout 协议不是必须要实现的,可以通过属性来设置,例如
- - (void)viewDidLoad {
- [super viewDidLoad];
-
- _dataSource = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil nil];
-
- UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
- layout.scrollDirection = UICollectionViewScrollDirectionVertical;
- layout.itemSize = CGSizeMake(96, 96);
- layout.minimumInteritemSpacing = 20.0;
- layout.minimumLineSpacing = 20.0;
- layout.headerReferenceSize = CGSizeMake(100.0, 50.0);
- layout.footerReferenceSize = CGSizeMake(100.0, 50.0);
- layout.sectionInset = UIEdgeInsetsMake(0, 10.0, 0, 10.0);
- UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
- [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
- collectionView.delegate = self;
- collectionView.dataSource = self;
-
- [self.view addSubview:collectionView];
- }
或者在创建UICollectionViewDelegateFlowLayout的时候不设置itemSize,然后在协议中设置
- #pragma mark -
- #pragma mark - UICollectionViewDelegateFlowLayout
-
- - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
- return CGSizeMake(96, 96);
- }
-
-
- - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
- return UIEdgeInsetsMake(10, 10, 10, 10);
- }
Item的宽高
一般情况下每个Item的宽高是一致的,但也可以不一致(需要实现UICollectionViewDelegateFlowLayout协议来定制)
3. 示例代码
① 基础示例:
- #import <UIKit/UIKit.h>
-
- @interface ViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
-
- @property (nonatomic, retain) NSArray * dataSource;
-
- @end
- #import "ViewController.h"
-
-
- @interface ViewController ()
-
- @end
-
- @implementation ViewController
-
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.title = @"UICollectionView Demo";
-
- _dataSource = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil nil];
-
- UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
- layout.scrollDirection = UICollectionViewScrollDirectionVertical;
-
- UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
- [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
- collectionView.delegate = self;
- collectionView.dataSource = self;
-
- [self.view addSubview:collectionView];
- }
-
- #pragma mark -
- #pragma mark - UICollectionViewDataSource
-
- - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
- return 1;
- }
-
-
- - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
- return _dataSource.count;
- }
-
-
- - (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
- static NSString * CellIdentifier = @"Cell";
- UICollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
- cell.backgroundColor = [UIColor grayColor];
-
- UIView * contentView = [[UIView alloc] init];
- UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 50, 50)];
- label.text = _dataSource[indexPath.row];
- [contentView addSubview:label];
-
- cell.backgroundView = contentView;
-
- return cell;
- }
-
- #pragma mark -
- #pragma mark - UICollectionViewDelegateFlowLayout
-
- - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
- return CGSizeMake(96, 96);
- }
-
-
- - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
- return UIEdgeInsetsMake(10, 10, 10, 10);
- }
-
- #pragma mark -
- #pragma mark - UICollectionView Deleage
-
- - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
- return YES;
- }
-
- - (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
- NSLog(@"row:%ld----------section: %ld", indexPath.row, indexPath.section);
- }
滚动方向:垂直, 分4区段,效果如下 滚动方向:水平, 分3区段,效果如下
② 段头
- - (void)viewDidLoad {
- [super viewDidLoad];
- _dataSource = [NSArray arrayWithObjects:@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", nil nil];
-
- UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
- layout.scrollDirection = UICollectionViewScrollDirectionVertical;
- layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
- layout.headerReferenceSize = CGSizeMake(300, 60);
-
- UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
- [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
-
-
- [collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"ReusableView"];
-
- collectionView.delegate = self;
- collectionView.dataSource = self;
-
- [self.view addSubview:collectionView];
- }
-
-
-
- - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
-
- UICollectionReusableView * headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
- withReuseIdentifier:@"ReusableView"
- forIndexPath:indexPath];
- UIView * contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
- contentView.backgroundColor = [UIColor grayColor];
- UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, self.view.frame.size.width, 30)];
- label.text = [NSString stringWithFormat:@"Section Header: %ld", indexPath.section];
- label.textAlignment = NSTextAlignmentCenter;
- [contentView addSubview:label];
-
-
- [headerView addSubview:contentView];
- return headerView;
- }
效果如图:
③ 自定义Cell
- #import <UIKit/UIKit.h>
-
- @interface CollectionViewCell : UICollectionViewCell
-
- @property (nonatomic, retain) UIImageView * imageView;
- @property (nonatomic, retain) UILabel * textLabel;
-
- @end
- #import "CollectionViewCell.h"
-
- @implementation CollectionViewCell
-
-
- - (id) initWithFrame:(CGRect)frame {
- if (self = [super initWithFrame:frame]) {
- self.backgroundColor = [UIColor grayColor];
-
- CGFloat itemWidth = self.frame.size.width;
- CGFloat itemHeight = self.frame.size.height;
-
- _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, itemWidth, itemHeight - 30)];
- [self addSubview:_imageView];
-
- _textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, itemHeight - 20, itemWidth, 20)];
- _textLabel.textAlignment = NSTextAlignmentCenter;
-
- [self addSubview:_textLabel];
-
- }
-
- return self;
- }
-
- @end
- - (void)viewDidLoad {
- [super viewDidLoad];
- self.title = @"UICollectionView Demo";
-
- UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc] init];
- layout.scrollDirection = UICollectionViewScrollDirectionVertical;
- layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
-
- UICollectionView * collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
- [collectionView registerClass:[CollectionViewCell class] forCellWithReuseIdentifier:@"Cell"];
- collectionView.delegate = self;
- collectionView.dataSource = self;
-
- [self.view addSubview:collectionView];
- }
-
-
- - (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
- static NSString * CellIdentifier = @"Cell";
- CollectionViewCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
- cell.backgroundColor = [UIColor grayColor];
-
-
- cell.imageView.image = [UIImage imageNamed:@"cat"];
- cell.textLabel.text = @"闰土";
-
- return cell;
- }
其他省略掉的代码和上个示例的完全一样,效果如图:
实例代码下载: http://download.csdn.net/detail/vbirdbest/9441547
使用UICollectionView注意事项:
1. 初始化时必须指定布局
2.必须注册Cell
3. 一般要自定义cell