UICollectionView是Apple在iOS6開始,提供給咱們的一個強大的控件。最簡單的UICollectionView就是GridView,標準的UICollectionView包含以下幾個部分:設計模式
1 UICollectionReusableView<SupplementaryView>:能夠指定section的Header或者Footer 2 UICollectionViewCell:用於展現內容的主體,對於不一樣的cell能夠指定不一樣尺寸和不一樣的內容
再次說明,UICollectionView的用法毫不止簡單的幾種!ide
實現一個簡單的UICollectionView佈局
UICollectionView的實現和UITableView相似,都是數據源(datasource)和代理(delegate)設計模式。datasource:提供數據源,告訴UICollectionView須要顯示什麼東西;delegate:代理,用於實現和用戶交互。優化
1 /// 必須實現的數據源方法 2 /** 3 返會cell的數量 4 */ 5 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section; 6 7 /** 8 返會cell視圖 9 */ 10 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath; 11 12 13 /// 可選實現的數據源方法 14 /** 15 返會section的數量 16 */ 17 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView; 18 19 /** 20 返回頭部或尾部 21 */ 22 - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath; 23 24 /** 25 iOS9系提供的方法,和cell的移動有關 26 */ 27 - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath; 28 - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath;
爲了更高效的使用cell,實現重用是必須的,值得注意的是,UICollectionViewCell使用以前必須先註冊cellatom
1 /** 2 註冊cell 3 */ 4 - (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier; 5 - (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier; 6 7 /** 8 註冊頭部尾部 9 */ 10 - (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier; 11 - (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;
對比於UITableViewCell的重用,蘋果對UICollectionViewCell的重用作了優化,並未提供以下代碼實現的方法:spa
1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 2 static NSString *reuseIdetifier = @"UITableViewCell"; 3 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 4 if (!cell) { 5 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; 6 } 7 return cell; 8 }
分析:UICollectionViewCell起初註冊了cell,咱們只須要在數據源方法裏面書寫以下代碼便可,不須要每次都判斷cell是否存在。要是在重用隊列裏沒有可用的cell的話,runtime將自動幫咱們生成並初始化一個可用的cell。設計
/** 註冊cell */ [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier]; /** 實現數據源方法 */ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; return cell; }
UICollectionViewLayout,佈局,之因此能實現各類效果,全依賴於這個類!UICollectionViewFlowLayout是蘋果給咱們實現好的一個相似流水佈局的佈局類。下面,來講明一下UICollectionViewFlowLayout的屬性:代理
/** 每一行cell的最小間距 */ @property (nonatomic) CGFloat minimumLineSpacing; /** cell之間的最小間距 */ @property (nonatomic) CGFloat minimumInteritemSpacing; /** cell的尺寸(若是cell尺寸是固定的,直接指定該屬性便可,不須要另外實現代理方法再去計算尺寸) */ @property (nonatomic) CGSize itemSize; /** 估算的cell尺寸 */ @property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0); /** 指定UICollectionView滾動方法 */ @property (nonatomic) UICollectionViewScrollDirection scrollDirection; /** 頭部尺寸 */ @property (nonatomic) CGSize headerReferenceSize; /** 尾部尺寸 */ @property (nonatomic) CGSize footerReferenceSize; /** 指定 UICollectionView 總體視圖的上、左、下、右的縮進(間距) */ @property (nonatomic) UIEdgeInsets sectionInset; /** iOS9新提供的,能夠實現頭部和尾部的懸浮效果 */ @property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0); @property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
tip:當UICollectionView內容不足以佔滿整屏時會出現不能滑動的現場,如下爲實現可滑動的方法:code
/// 建議只把和佈局滾動方向一致的bounce設置爲YES // 狀況一 flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; collectionView.alwaysBounceVertical = YES; // 狀況二 flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; collectionView.alwaysBounceHorizontal = YES;
尊重做者勞動成果,轉載請註明: 【kingdev】blog