美文网首页
UICollectionView

UICollectionView

作者: BernardChina | 来源:发表于2016-11-11 10:15 被阅读88次

在我们的工作过程中,经常用到的是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

      本文链接:https://www.haomeiwen.com/subject/ddxtpttx.html