UICollectionView

在我们的工作过程中,经常用到的是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(补充试图),我们sectionheaderfooter是用它实现的,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 viewdecoration 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 什么是UICollectionView? UICollectionView是一种新的数据展示方式,简单来说可以把他...
    凌峰Mical阅读 43,426评论 11 201
  • //联系人:石虎 QQ: 1224614774昵称:嗡嘛呢叭咪哄 什么是UICollectionView UICo...
    石虎132阅读 3,454评论 0 15
  • UICollectionView是一种类似于UITableView但又比UITableView功能更强大、更灵活的...
    浪漫紫薇星阅读 1,107评论 0 0
  • 再次敲击电脑的键盘已是新年头的开始,手指似乎跟不上头脑的流水般的思考,然而,曾经或是现在的思索却没有经过一年的沉淀...
    天线的触角阅读 215评论 0 0
  • 动量的东西基本搞通了想一下要做哪些动量的处理 首先之前处理缝轴向动量的结果都要改其次要处理几个处理缝开口的轴向动量...
    中场休息室阅读 156评论 0 0