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"];

然后實現(xiàn)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是用它實現(xiàn)的,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 準備一些基本數(shù)據(jù)
    [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的時候,我認為它是發(fā)動機
    NSMutableArray* attributes = [NSMutableArray array];
    //把Decoration View的布局加入可見區(qū)域布局。
    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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 什么是UICollectionView? UICollectionView是一種新的數(shù)據(jù)展示方式,簡單來說可以把他...
    凌峰Mical閱讀 43,688評論 11 201
  • //聯(lián)系人:石虎 QQ: 1224614774昵稱:嗡嘛呢叭咪哄 什么是UICollectionView UICo...
    石虎132閱讀 3,614評論 0 15
  • UICollectionView是一種類似于UITableView但又比UITableView功能更強大、更靈活的...
    浪漫紫薇星閱讀 1,162評論 0 0
  • 再次敲擊電腦的鍵盤已是新年頭的開始,手指似乎跟不上頭腦的流水般的思考,然而,曾經或是現(xiàn)在的思索卻沒有經過一年的沉淀...
    天線的觸角閱讀 223評論 0 0
  • 動量的東西基本搞通了想一下要做哪些動量的處理 首先之前處理縫軸向動量的結果都要改其次要處理幾個處理縫開口的軸向動量...
    中場休息室閱讀 175評論 0 0

友情鏈接更多精彩內容