在我们的工作过程中,经常用到的是UITableView
.本文章首先从两个方面介绍UICollectionView
.首先介绍和UITableView
的不同,并且一些基本的用法,然后会介绍UICollectionView
的自定义layout
。
和UITableView不同,一些基本用法
初始化
UITableView
直接init
就可以了,初始化UICollectionView
必须制定layout
tableView初始化
UITableView *tableView = [[UITableView alloc] init];
collectionView初始化
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(100, 100);
layout.minimumLineSpacing = 20;
layout.minimumInteritemSpacing = 10;
layout.headerReferenceSize = CGSizeMake(self.view.frame.size.width, 100);
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) collectionViewLayout:layout];
** collectionView
必须自定义collectionViewCell
**
tableView和collectionView都有datasource和delegate.所以,如果获取cell的方法中,没有初始化cell,会报错
错误的做法:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// 如果仅仅这么写,是有问题的。在tableview中是没有问题的
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
if (!cell) {
cell = [[UICollectionViewCell alloc] init];
}
cell.backgroundColor = [UIColor redColor];
return cell;
}
正确的做法:
-(void)viewDidLoad {
[self.collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
if (!cell) {
cell = [[MyCollectionViewCell alloc] init];
}
cell.backgroundColor = [UIColor redColor];
return cell;
}
section header
的不同
tableView
就不过多的阐述。collectionView
增加了Supplementary
视图
首先注册section header view
[self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"reusableView"];
然后实现datasource
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"reusableView" forIndexPath:indexPath];
headerView.backgroundColor = [UIColor blueColor];
return headerView;
}
return nil;
}
同时设置header的size
// 在初始化layout的时候
layout.headerReferenceSize = CGSizeMake(self.view.frame.size.width, 100);
自定义CollectionViewLayout
大部分情况下xcode
提供的默认瀑布流布局UICollectionViewFlowLayout
就可以使用。但是,我们还是介绍一下自定义layout说用到的一些方法
首先 UICollectionView
增加了两种视图Supplementary
(补充试图),我们section
的header
和footer
是用它实现的,datasource
提供了相应的delegate
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"reusableView" forIndexPath:indexPath];
headerView.backgroundColor = [UIColor blueColor];
return headerView;
}
return nil;
}
还增加了另外一种视图,装饰视图(Decoration)
视图,这种视图可以提供诸如背面图版(backdrop
)等视觉增强效果.
有一点要记住的是,decoration views完全是由layout管理的,与cell或supplementary views不一样,它不在collection view data source的管辖范围内
下面会贴出一些代码,自定义layout
首先定义继承于UICollectionViewLayout
的自定义layout
.h
@interface MyCollectionViewLayout : UICollectionViewLayout
@end
.m
@implementation MyCollectionViewLayout
- (void)prepareLayout {
// prepareLayout 准备一些基本数据
[super prepareLayout];
[self registerClass:[MyCollectionReusableView class] forDecorationViewOfKind:@"CDV"];
}
- (CGSize)collectionViewContentSize {
return self.collectionView.frame.size;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
// 此方法是设置每一个item的一些显示,是通过layoutAttributesForElementsInRect调用的
UICollectionViewLayoutAttributes* attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath ];
attributes.size = CGSizeMake(215/3.0, 303/3.0);
attributes.center=CGPointMake(80*(indexPath.item+1), 62.5+125*indexPath.section);
return attributes;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {
// 如果collectionview需要装饰视图,比如背景啊,书架等
UICollectionViewLayoutAttributes* att = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:elementKind withIndexPath:indexPath];
att.frame=CGRectMake(0, (125*indexPath.section)/2.0, 320, 125);
att.zIndex=-1;
return att;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
// 这是最酷的方法,加载整个layout的时候,我认为它是发动机
NSMutableArray* attributes = [NSMutableArray array];
//把Decoration View的布局加入可见区域布局。
for (int y=0; y<3; y++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:3 inSection:y];
[attributes addObject:[self layoutAttributesForDecorationViewOfKind:@"CDV"atIndexPath:indexPath]];
}
for (NSInteger i=0 ; i < 3; i++) {
for (NSInteger t=0; t<3; t++) {
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:t inSection:i];
[attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
}
}
return attributes;
}
每个cell view、supplemental view
和decoration view
都有layout
属性。想要知道layouts
如何灵活,只需看看 UICollectionViewLayoutAttributes
对象的特性就知道了:
frame
center
size
transform3D
alpha
zIndex
hidden
属性由你可能想要的那种委托方法指定:
-layoutAttributesForItemAtIndexPath:
-layoutAttributesForSupplementaryViewOfKind:atIndexPath:
-layoutAttributesForDecorationViewOfKind:atIndexPath:
这是最酷的方法:
-layoutAttributesForElementsInRect:
比较好的文章
http://nshipster.cn/uicollectionview/
对Decoration
视图使用http://kyoworkios.blog.51cto.com/878347/1341549
网友评论