為什麼要引入UICollectionView
UITableView的不足,無法實作更靈活的布局,UITableView無法實作右邊情況,無法實作自定義設定位置
關于UICollectionView的介紹
提供清單展示的容器,内置複用回收池,支援橫向+縱向布局,更加靈活的布局方式、動畫、裝飾視圖,布局之間的切換
與UITableView的比較
與UITableView有相同的Api設計理念–都是基于datasource以及delegate驅動
- row —> item (一行可展示多個視圖,row不能确定位置)
-
UICollectionViewDataSource替換UITableViewDataSouece
處理資料的邏輯(多少内容)
-
UICollectionViewDelegate替換UITableViewDelegate
處理滾動和展示的邏輯
- 不提供預設的樣式(不以"行"為設計基礎,隻有contentView/backgroundView , 內建自UICollectionReusableView)
- 必須先注冊Cell 類型作為重用
UIConllectionView的簡單實踐
1. 建立GTVideoViewController
command+N 建立 Cocoa Touch Class,如圖:
2. 初始化代碼(可以設定該部分的title值以及圖檔資訊)
-(instancetype) init{
self = [super init];
if(self){
self.tabBarItem.title = @"視訊"; //這裡是作為一個UITabBarController的一個部分
}
return self;
}
3. 聲明協定
@interface GTVideoViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
@end
4. 在viewDidLoad部分,為該部分增添collectionView
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
UICollectionView *collectionView = [[UICollectionView alloc ]initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
collectionView.delegate = self;
collectionView.dataSource = self;
[collectionView registerClass: [UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
[self.view addSubview:collectionView];
}
5. 實作UICollectionView的代理方法,對于UICollectionView部分,設定Cell的數量和每一個Cell
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 20;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
return cell;
}
運作後的效果圖(Cell預設:50*50)
完整代碼
#import "GTVideoViewController.h"
@interface GTVideoViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
@end
@implementation GTVideoViewController
-(instancetype) init{
self = [super init];
if(self){
self.tabBarItem.title = @"視訊";
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
UICollectionView *collectionView = [[UICollectionView alloc ]initWithFrame:self.view.bounds collectionViewLayout:flowLayout];
collectionView.delegate = self;
collectionView.dataSource = self;
[collectionView registerClass: [UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
[self.view addSubview:collectionView];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 20;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
return cell;
}
@end
UICollectionViewLayout
UICollectionViewLayout對應着UICollectionViewLayoutAttributes,在UICollectionViewLayoutAttributes中可以實作更細節的布局
1. 設定Cell之間的間距、最小行間距以及Cell的高度
運作結果
代碼部分
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.minimumLineSpacing = 10;
flowLayout.minimumInteritemSpacing = 10;
flowLayout.itemSize = CGSizeMake((self.view.frame.size.width -10)/2, 300);
2. 通過indexPath來設定Cell的樣式
運作結果
代碼部分
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(nonnull NSIndexPath *)indexPath{
if(indexPath.item%3==0){
return CGSizeMake(self.view.frame.size.width, 100);
}else{
return CGSizeMake((self.view.frame.size.width - 10)/2, 300);
}
}