UICollectionView 和 UICollectionViewController 類是iOS6 新引進的API,用于展示集合視圖,布局更加靈活,可實現多列布局,用法類似于UITableView 和 UITableViewController 類。
我們來按順序看下面四幅圖。可以看出,UICollectionViewCell與UITableViewCell的結構很相似。
下圖是UICollectionView相關的類圖,從圖中我們可以看到
1. UICollectionView繼承自UIScrollView,
2. 尊循UICollectionViewDelegate和UICollectionViewDataSource兩個協議
3. 管理UICollectionViewCell
圖
中貌似還缺點東西,什么呢?對了,就是缺少Layout。我們需要Layout對cell和其它的view進行布局。再看下圖,圖中多了
UICollectionViewLayout和UICollectionViewFlowLayout
(關于這兩個layout,我會在下面兩節中介紹到)。
如下面的兩個圖是collection view的layout。
CollectionView主要是以Item為基本單元,可以看出,每個Item不一定占滿一行,而tableView的Cell必須占滿一行。
典型的例子:九宮格。
UITableView的實現思路:
1. 自定義一個UITableViewCell。
2. 在自定義的Cell的contentView上面放置所需要的元素。
3. 為每一個放置的元素添加點擊事件,而且還要計算好每個元素所在的位置。
UICollectionView的實現思路
每一個Item就是一個Cell,而點擊事件直接交給UICollectionView的代理方法就可以了。
先看實現的效果圖:
代碼大致實現步驟如下:
1. 自定義UICollectionViewCell,就是上圖中對應的每一個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];
? ? // 注冊LFCollectionViewCell
? ? [self.collectionView registerClass:[LFCollectionViewCell class] forCellWithReuseIdentifier:@"LFCollection"];
}
#pragma mark - UICollectionView DataSource// 每個section的item個數
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
? ? return 8;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
? ? // UICollectionViewCell內部已經實現了循環使用,所以不用判斷為空,自己創建? ? LFCollectionViewCell *cell = (LFCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"LFCollection" forIndexPath:indexPath];? ? ? ? //圖片名稱
NSString *image = [NSString stringWithFormat:@"%ld.jpg", (long)indexPath.row];? ? ? ?
//加載圖片
?cell.myImage.image = [UIImage imageNamed:image];? ? ? ?
//設置label文字
cell.myLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
return cell;
}
@end
需要說明的兩點:
1. 在viewDidload中完成LFCollectionViewCell的注冊。
2. 在dequeueReusableCellWithReuseIdentifer方法從緩存池中獲取的cell不需要判斷取出來的cell是否為nil,如果為nil,系統會自動創建一個。
3. 如果改變圖片的尺寸,只要當屏幕的一行不夠顯示圖片的時候,圖片會自動換行。
4. 想要實現每個Item的點擊實現,只要在代理中實現就可以了。
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
}