《iOS开发笔记—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  */






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)sectionUITabBarController和UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型的例子就是QQ、微信等应。

UITabBarController的使用
1.使用步骤:
(1)初始化UITabBarController
(2)设置UIWindow的rootViewController为UITabBarController
(3)创建相应的子控制器(viewcontroller)
(4)把子控制器添加到UITabBarController

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值