UICollectionView在目前的iOS開發(fā)中,使用非常廣泛懦胞,它可以完成許多UITableView完成不了的復(fù)雜的布局替久,在使用上,兩者也有著許多的相似之處躏尉,主要體現(xiàn)在布局的樣式上蚯根,UITableView主要有兩種布局:plain和group,而UICollectionView則可以根據(jù)我們的需要自定義各種各樣復(fù)雜的布局胀糜,這也是下面我們就UICollectionView的使用進(jìn)行一下詳細(xì)的解析颅拦。
基本使用方法
與UITableView相似,在UICollectionView時(shí)教藻,也要遵循數(shù)據(jù)源(UICollectionViewDataSource)與代理協(xié)議方法(UICollectionViewDelegate)距帅,也要注冊(cè)cell片排,與UITableView不同的是纺座,我們還需要為UICollectionView創(chuàng)建一個(gè)布局參數(shù),也就是UICollectionViewFlowLayout艳悔,這也是UICollectionView的精髓所在悄窃,正是通過它讥电,我們才實(shí)現(xiàn)了UICollectionView各式各樣的布局,這我們?cè)诤竺鏁?huì)一一講述轧抗,有興趣的同學(xué)也可以看一下蘋果官方文檔恩敌。
系統(tǒng)為我們提供了兩個(gè)UICollectionView的布局類:UICollectionViewLayout和UICollectionViewFlowLayout,UICollectionViewLayout類是一個(gè)抽象類横媚,我們?cè)谧远x布局的時(shí)候可以繼承此類纠炮,并在此基礎(chǔ)上設(shè)置布局信息,UICollectionViewFlowLayout繼承于UICollectionViewLayout分唾,是系統(tǒng)為我們寫好的布局類,該類為我們提供了一個(gè)簡(jiǎn)單的布局樣式狮斗,假如我們只需要一個(gè)特別簡(jiǎn)單的網(wǎng)格布局或者流水布局绽乔,可以直接使用它。
創(chuàng)建UICollectionView的基本代碼如下:
初始化
/**
創(chuàng)建layout
*/
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
/**
創(chuàng)建collectionView
*/
UICollectionView* collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 64, kScreenWidth, kScreenHeight-64) collectionViewLayout:layout];
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.backgroundColor = [UIColor cyanColor];
/**
注冊(cè)item和區(qū)頭視圖碳褒、區(qū)尾視圖
*/
[collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MyCollectionViewCell"];
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"MyCollectionViewHeaderView"];
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"MyCollectionViewFooterView"];
[self.view addSubview:collectionView];
實(shí)現(xiàn)協(xié)議方法
#pragma mark - UICollectionViewDelegate,UICollectionViewDataSource
/**
分區(qū)個(gè)數(shù)
*/
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
/**
每個(gè)分區(qū)item的個(gè)數(shù)
*/
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return _imagesArray.count;
}
/**
創(chuàng)建cell
*/
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"MyCollectionViewCell";
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor cyanColor];
cell.imageStr = _imagesArray[indexPath.item];
return cell;
}
/**
創(chuàng)建區(qū)頭視圖和區(qū)尾視圖
*/
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
if (kind == UICollectionElementKindSectionHeader){
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"MyCollectionViewHeaderView" forIndexPath:indexPath];
headerView.backgroundColor = [UIColor yellowColor];
UILabel *titleLabel = [[UILabel alloc]initWithFrame:headerView.bounds];
titleLabel.text = [NSString stringWithFormat:@"第%ld個(gè)分區(qū)的區(qū)頭",indexPath.section];
[headerView addSubview:titleLabel];
return headerView;
}else if(kind == UICollectionElementKindSectionFooter){
UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"MyCollectionViewFooterView" forIndexPath:indexPath];
footerView.backgroundColor = [UIColor blueColor];
UILabel *titleLabel = [[UILabel alloc]initWithFrame:footerView.bounds];
titleLabel.text = [NSString stringWithFormat:@"第%ld個(gè)分區(qū)的區(qū)尾",indexPath.section];
[footerView addSubview:titleLabel];
return footerView;
}
return nil;
}
/**
點(diǎn)擊某個(gè)cell
*/
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"點(diǎn)擊了第%ld分item",(long)indexPath.item);
}
/**
cell的大小
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
CGFloat itemW = (kScreenWidth-(kLineNum+1)*kLineSpacing)/kLineNum-0.001;
return CGSizeMake(itemW, itemW);
}
/**
每個(gè)分區(qū)的內(nèi)邊距(上左下右)
*/
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(kLineSpacing, kLineSpacing, kLineSpacing, kLineSpacing);
}
/**
分區(qū)內(nèi)cell之間的最小行間距
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
return kLineSpacing;
}
/**
分區(qū)內(nèi)cell之間的最小列間距
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
return kLineSpacing;
}
/**
區(qū)頭大小
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
return CGSizeMake(kScreenWidth, 65);
}
/**
區(qū)尾大小
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
return CGSizeMake(kScreenWidth, 65);
}
最終的效果圖如下:
上面我們提到了折砸,UICollectionViewFlowLayout是系統(tǒng)為我們提供的一個(gè)簡(jiǎn)單的流水布局,那么我們?cè)谥苯邮褂盟龊?jiǎn)單的布局時(shí)沙峻,可以直接設(shè)置它的一個(gè)屬性睦授,來達(dá)到我們布局的目的,這樣就可以省略掉一些UICollectionView協(xié)議方法的實(shí)現(xiàn)摔寨。
我們來看一下UICollectionViewFlowLayout都有哪些屬性可以設(shè)置:
和上面我們實(shí)現(xiàn)的UICollectionView中的一些協(xié)議方法的名字非常相似去枷,根據(jù)名字應(yīng)該可以一一對(duì)應(yīng)。
那么,使用UICollectionViewFlowLayout的屬性設(shè)置布局的效果如果呢删顶,我們來看:
代碼實(shí)現(xiàn)
/**
創(chuàng)建layout
*/
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
/**
設(shè)置item的行間距和列間距
*/
layout.minimumInteritemSpacing = kLineSpacing;
layout.minimumLineSpacing = kLineSpacing;
/**
設(shè)置item的大小
*/
CGFloat itemW = (kScreenWidth-(kLineNum+1)*kLineSpacing)/kLineNum-0.001;
layout.itemSize = CGSizeMake(itemW, itemW);
/*
設(shè)置每個(gè)分區(qū)的上左下右的內(nèi)邊距
*/
layout.sectionInset = UIEdgeInsetsMake(kLineSpacing, kLineSpacing,kLineSpacing, kLineSpacing);
/**
設(shè)置區(qū)頭和區(qū)尾的大小
*/
layout.headerReferenceSize = CGSizeMake(kScreenWidth, 65);
layout.footerReferenceSize = CGSizeMake(kScreenWidth, 65);
/**
設(shè)置分區(qū)的頭視圖和尾視圖是否始終固定在屏幕上邊和下邊
*/
layout.sectionFootersPinToVisibleBounds = YES;
/**
創(chuàng)建collectionView
*/
UICollectionView* collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 64, kScreenWidth, kScreenHeight-64) collectionViewLayout:layout];
collectionView.delegate = self;
collectionView.dataSource = self;
collectionView.backgroundColor = [UIColor cyanColor];
[collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"MyCollectionViewCell"];
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"MyCollectionViewHeaderView"];
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"MyCollectionViewFooterView"];
[self.view addSubview:collectionView];
#pragma mark - UICollectionViewDelegate,UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return _imagesArray.count;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = @"MyCollectionViewCell";
MyCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor cyanColor];
cell.imageStr = _imagesArray[indexPath.item];
return cell;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
if (kind == UICollectionElementKindSectionHeader){
UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"MyCollectionViewHeaderView" forIndexPath:indexPath];
headerView.backgroundColor = [UIColor yellowColor];
UILabel *titleLabel = [[UILabel alloc]initWithFrame:headerView.bounds];
titleLabel.text = [NSString stringWithFormat:@"第%ld個(gè)分區(qū)的區(qū)頭",indexPath.section];
[headerView addSubview:titleLabel];
return headerView;
}else if(kind == UICollectionElementKindSectionFooter){
UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"MyCollectionViewFooterView" forIndexPath:indexPath];
footerView.backgroundColor = [UIColor blueColor];
UILabel *titleLabel = [[UILabel alloc]initWithFrame:footerView.bounds];
titleLabel.text = [NSString stringWithFormat:@"第%ld個(gè)分區(qū)的區(qū)尾",indexPath.section];
[footerView addSubview:titleLabel];
return footerView;
}
return nil;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@"點(diǎn)擊了第%ld分item",(long)indexPath.item);
}
效果圖:
事實(shí)證明竖螃,兩種方法在實(shí)現(xiàn)的效果上并沒有任何區(qū)別。
總結(jié)
關(guān)于UICollectionView的基本使用大概就是這些內(nèi)容逗余,但是這些只適用于一些簡(jiǎn)單的網(wǎng)格或流水布局特咆,如果遇到比較復(fù)雜的布局,比如瀑布流等录粱,就需要自定義UICollectionViewLayout來布局了腻格。在下一篇文章中,我們會(huì)詳細(xì)介紹如何使用自定義UICollectionViewLayout來編寫復(fù)雜布局啥繁。
在下一篇文章中菜职,我將為大家介紹如何使用自定的UICollectionViewLayout來實(shí)現(xiàn)復(fù)雜的布局。