UICollectionView 和 UICollectionViewController 類是iOS6 新引進(jìn)的API煮嫌,用于展示集合視圖,布局更加靈活,可實(shí)現(xiàn)多列布局惫叛,用法類似于UITableView 和 UITableViewController 類。
我們來(lái)按順序看下面四幅圖逞刷〖斡浚可以看出,UICollectionViewCell與UITableViewCell的結(jié)構(gòu)很相似夸浅。
下圖是UICollectionView相關(guān)的類圖仑最,從圖中我們可以看到
1. UICollectionView繼承自UIScrollView,
2. 尊循UICollectionViewDelegate和UICollectionViewDataSource兩個(gè)協(xié)議
3. 管理UICollectionViewCell
圖
中貌似還缺點(diǎn)東西帆喇,什么呢警医?對(duì)了,就是缺少Layout坯钦。我們需要Layout對(duì)cell和其它的view進(jìn)行布局预皇。再看下圖,圖中多了
UICollectionViewLayout和UICollectionViewFlowLayout
(關(guān)于這兩個(gè)layout婉刀,我會(huì)在下面兩節(jié)中介紹到)吟温。
如下面的兩個(gè)圖是collection view的layout。
CollectionView主要是以Item為基本單元突颊,可以看出鲁豪,每個(gè)Item不一定占滿一行潘悼,而tableView的Cell必須占滿一行。
典型的例子:九宮格爬橡。
UITableView的實(shí)現(xiàn)思路:
1. 自定義一個(gè)UITableViewCell治唤。
2. 在自定義的Cell的contentView上面放置所需要的元素。
3. 為每一個(gè)放置的元素添加點(diǎn)擊事件堤尾,而且還要計(jì)算好每個(gè)元素所在的位置肝劲。
UICollectionView的實(shí)現(xiàn)思路
每一個(gè)Item就是一個(gè)Cell,而點(diǎn)擊事件直接交給UICollectionView的代理方法就可以了郭宝。
先看實(shí)現(xiàn)的效果圖:
代碼大致實(shí)現(xiàn)步驟如下:
1. 自定義UICollectionViewCell辞槐,就是上圖中對(duì)應(yīng)的每一個(gè)Item。
LFCollectionViewCell.h
@interfaceLFCollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UIImageView *myImage粘室;
@property (weak, nonatomic) IBOutlet UILabel *myLabel;
@end
LFCollectionViewCell.m
@implementation LFCollectionViewCell
- (void)awakeFromNib
{
? // Initialization code
}
- (instancetype)initWithFrame:(CGRect)frame
{
? ? if(self = [super initWithFrame:frame])
?? {
? ? ? self = [[[NSBundle mainBundle] loadNibNamed:@"LFCollectionViewCell" owner:nil options:nil] lastObject];
? ? }
? return self;
}
@end
2. 主界面代碼:
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
? ? [super viewDidLoad];
? ? // 注冊(cè)LFCollectionViewCell
? ? [self.collectionView registerClass:[LFCollectionViewCell class] forCellWithReuseIdentifier:@"LFCollection"];
}
#pragma mark - UICollectionView DataSource// 每個(gè)section的item個(gè)數(shù)
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
? ? return 8;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
? ? // UICollectionViewCell內(nèi)部已經(jīng)實(shí)現(xiàn)了循環(huán)使用榄檬,所以不用判斷為空,自己創(chuàng)建? ? LFCollectionViewCell *cell = (LFCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"LFCollection" forIndexPath:indexPath];? ? ? ? //圖片名稱
NSString *image = [NSString stringWithFormat:@"%ld.jpg", (long)indexPath.row];? ? ? ?
//加載圖片
?cell.myImage.image = [UIImage imageNamed:image];? ? ? ?
//設(shè)置label文字
cell.myLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
return cell;
}
@end
需要說(shuō)明的兩點(diǎn):
1. 在viewDidload中完成LFCollectionViewCell的注冊(cè)衔统。
2. 在dequeueReusableCellWithReuseIdentifer方法從緩存池中獲取的cell不需要判斷取出來(lái)的cell是否為nil鹿榜,如果為nil,系統(tǒng)會(huì)自動(dòng)創(chuàng)建一個(gè)锦爵。
3. 如果改變圖片的尺寸舱殿,只要當(dāng)屏幕的一行不夠顯示圖片的時(shí)候,圖片會(huì)自動(dòng)換行险掀。
4. 想要實(shí)現(xiàn)每個(gè)Item的點(diǎn)擊實(shí)現(xiàn)沪袭,只要在代理中實(shí)現(xiàn)就可以了。
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
}