美文网首页
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