您的位置:首页 > 产品设计 > UI/UE

如何创建一个UICollectionView之使用详解

2016-04-06 16:46 666 查看
游小龙的技术博客点击阅读更多

1 UICollectionView的前世今生

UICollectionView在iOS6(2012年6提出的)中首次被提出(现在已经是iOS9),它和UITableView共享API设计,在上面做了一些灵活扩展。UICollectionViewDataSource(数据源)、UICollectionViewDelegateFlowLayout(视图布局)、UICollectionViewDelegate。

UICollectionViewFlowLayout:视图布局对象(流视图:一行排满,自动排到下行),继承自UICollectionViewLayout。

2 UICollectionView的布局

UICollectionView是由UICollectionViewDelegateFlowLayout(视图布局)UICollectionViewDataSource(数据源)UICollectionViewDelegate这三个驱动的。

他们为其显示的子视图集扮演为愚蠢的容器(dumb containers),对他们真实的内容(contents)毫不知情。

2.1UICollectionViewLayout

UICollectionView进一步抽象了。它将其子视图的位置,大小和外观的控制权委托给一个单独的布局对象。通过提供一个自定义布局对象,你几乎可以实现任何你能想象到的布局。布局继承自UICollectionViewLayout这个抽象基类。

一下是在UICollectionViewLayout终须实现的3个类

**

2.1.1—–返回对应于indexPath的位置的cell的布局属性 获取某个indexPath下cell的LayoutAttributes信息—–

**

(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath


**

2.1.2—-获取在某个区域内(以contentSize为依据)可见cell的Attributes信息,这个函数需要获取这个可见区域内的indexPath的范围,而获取indexPath范围的方法需要获取某个点上cell的indexPath的方法,而这个方法又依赖于每个cell的size。—–

**

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect


2.1.3—-计算整个UICollectionView的contentSize,如果计算的大了,有可能会引起crash(具体情况取决于超出的尺寸是否会导致新的cell出现)—–

**

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect


手写我们的第一个UICollectionView

1.创建UICollectionView视图

先在.h文件设置属性 代理(这个够细致了哈 )

#import <UIKit/UIKit.h>

@interface View2 : UIViewController<UICollectionViewDelegate,UICollectionViewDataSource,UIScrollViewDelegate>
//这里之前写了weak   一直显示不了 坑我啊 啊哈啊啊啊啊啊
//@property (weak,nonatomic) UICollectionView *collectionView;
@property (nonatomic,strong) UICollectionView *collectionView;
@property (nonatomic,strong) UIButton *btn2;
@end


- (void)loadCollectionView
{
//1.定义布局对象
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 200.0f, width, height)                                    collectionViewLayout:[[CircleLayout alloc] init]];
//【CircleLayout这个是布局对象类继承UICollectionViewLayout】
//2.注册cell(sectionHeader、sectionFooter 这两个表头 跟表尾 不一定要实现)
[self.collectionView registerClass:[ShowImageCell class] forCellWithReuseIdentifier:cellId];
//【ShowImageCell这个是我们要实现的单元格cell】

//3.设置代理
self.collectionView.delegate = self;
self.collectionView.dataSource = self;

//一些其他处理的设置 非必要
self.collectionView.backgroundColor = [UIColor grayColor];
[self.collectionView setContentOffset:CGPointMake(width, 0.0F)];

[self.view addSubview:self.collectionView];


#import "View2.h"
//照片显示的类 collectionview
#import "CircleLayout.h"
#import "ShowImageCell.h"
//看这里
-----定义一个字符串来保存 单元格
方法一
#define cellId @"cellId"
#define headerId @"headerId"
#define footerId @"footerId"
方法二
// 注意const的位置
//static NSString *const KCellId = @"cellId";
//static NSString *const headerId = @"headerId";
//static NSString *const footerId = @"footerId";
@interface View2 ()


2.实现UICollectionViewDataSource的几个代理方法

#pragma mark - UICollectionViewDelegate
#pragma mark - UICollectionViewDataSource
//1.设置分区的个数
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
//2.设置返回的行数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 10;
}
##这个是重点哈 ##
//3.设置cell的样式
- (UICollectionViewCell *)collectionView:(UICollectionView *)cView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
//步骤1  设置重用的单元格 设重用表示符
ShowImageCell *cell = (ShowImageCell *)[cView dequeueReusableCellWithReuseIdentifier:CellId
forIndexPath:indexPath];
if (!cell) {
NSLog(@"不是吧 cell为nil");
return nil;
}
//步骤2  根据需要填写 cell显示格式(我这里是文字跟图片)
NSString *imageName = [NSString stringWithFormat:@"%d.JPG",indexPath.row];

cell.imageView.image = [UIImage imageNamed:imageName];
cell.titleLabel.text = imageName;
//步骤3  好吧 这一步 一个单元格重用就创建好了
return cell;
}

//还有一些其他代理根据需要 添加方法这里在多写一个 表头跟表尾
--------------------------------下面的可以不看了
// 和UITableView类似,UICollectionView也可设置段头段尾
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if([kind isEqualToString:UICollectionElementKindSectionHeader])
{
UICollectionReusableView *headerView = [_collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:headerId forIndexPath:indexPath];
if(headerView == nil)
{
headerView = [[UICollectionReusableView alloc] init];
}
headerView.backgroundColor = [UIColor grayColor];
return headerView;
}
else if([kind isEqualToString:UICollectionElementKindSectionFooter])
{
UICollectionReusableView *footerView = [_collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:footerId forIndexPath:indexPath];
if(footerView == nil)
{
footerView = [[UICollectionReusableView alloc] init];
}
footerView.backgroundColor = [UIColor lightGrayColor];
return footerView;
}
return nil;
}


3.接下来我们实现布局

3.1新建一个类 继承 UICollectionViewLayout

//.h文件
#import <UIKit/UIKit.h>
@interface CircleLayout : UICollectionViewLayout
@end


3.2在.m文件中实现3个必要方法 前面有提到哈

#import "CircleLayout.h"
//这个类就控制布局的
@implementation CircleLayout
//一
-(CGSize)collectionViewContentSize
{
return size;
}
//二
#pragma mark - UICollectionViewLayout
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return attributes;
}
//三
-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
return attributes;
}
@end


4.最后创建单元格 继承自UICollectionViewCell

步骤一:继承  属性
#import <UIKit/UIKit.h>
@interface ShowImageCell : UICollectionViewCell
//这里写属性  单元格显示的信息
@property (nonatomic,strong) UIImageView *imageView;
@property (nonatomic,strong) UILabel   *titleLabel;
@end


步骤二:方法重写 实现
#import "ShowImageCell.h"
@implementation ShowImageCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code

_imageView = [[UIImageView alloc] init];
[self.contentView addSubview:_imageView];

_titleLabel = [[UILabel alloc] init];
_titleLabel.textColor = [UIColor whiteColor];
[self.contentView addSubview:_titleLabel];
}
return self;
}
//这是写在实现这里面的  不去调用也能实现
-(void)layoutSubviews{
_imageView.frame = self.contentView.bounds;
_titleLabel.frame = CGRectMake(0.0f,0.0f , self.contentView.bounds.size.width, 44.0f);
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: