UICollectionView簡介
UICollectionView在iOS6.0以后引進,與UITableView比較相似。但是UICollectionView將布局完全交給UICollectionViewLayout蓖扑,而且允許用戶自定義layout來進行布局唉铜。使其功能比UITableView更加強大、布局更加靈活律杠,迅速在各大APP廣泛使用潭流。
本篇將對UICollectionView的使用進行簡單介紹,主要包括UICollectionView的視圖組成柜去、數(shù)據(jù)源灰嫉、常用代理方法以及UICollectionViewFlowLayout的使用。下一遍將會詳細講解UICollectionViewLayout的自定義布局诡蜓。
UICollectionView的視圖組成:
UICollectionView由cell視圖熬甫、Supplementary View和Decoration View三部分組成。
cell視圖
這個大家應(yīng)該都很清楚蔓罚,UICollectionView主要內(nèi)容展示的視圖
Supplementary View
對于每組section的信息視圖椿肩,類似于UITableView的header或者footer
Decoration View
裝飾視圖,好像很少使用
cell視圖跟Supplementary View使用是需要先進行注冊以便實現(xiàn)復用:
注冊cell的方法豺谈,第一個是代碼創(chuàng)建郑象,第二個是xib創(chuàng)建
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;
注冊Supplementary View的方法,第一個是代碼創(chuàng)建茬末,第二個是xib創(chuàng)建
- (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;
在數(shù)據(jù)源回調(diào)中復用的方法:
- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
***上面方法的的kind和elementKind參數(shù)用來區(qū)分是頭部視圖還是尾部視圖
UICollectionView的數(shù)據(jù)源代理方法:
//必須實現(xiàn)的數(shù)據(jù)源代理
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
//可選數(shù)據(jù)源代理
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
處理移動相關(guān)(詳細使用看demo)
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath NS_AVAILABLE_IOS(9_0);
UICollectionView的常用代理方法:
//點擊cell高亮相關(guān)
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath;
//cell選中相關(guān)
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath; // called when the user taps on an already-selected item in multi-select mode
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
//cell以及Supplementary View繪制相關(guān)
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0);
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath;
***這幾個方法可以添加簡易的動畫,例如添加如下幾句代碼厂榛,cell加載的時候?qū)蟹趴s等效果。
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(8_0)
{
cell.contentView.alpha = 0;
cell.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(0, 0), 0);
[UIView animateKeyframesWithDuration:.5 delay:0.0 options:0 animations:^{
/**
* 分步動畫 第一個參數(shù)是該動畫開始的百分比時間 第二個參數(shù)是該動畫持續(xù)的百分比時間
*/
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.8 animations:^{
cell.contentView.alpha = .5;
cell.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(1.2, 1.2), 0);
}];
[UIView addKeyframeWithRelativeStartTime:0.8 relativeDuration:0.2 animations:^{
cell.contentView.alpha = 1;
cell.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(1, 1), 0);
}];
} completion:^(BOOL finished) {
}];
}
//長按顯示菜單相關(guān):(demo中有詳細使用)
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender;
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender;
//轉(zhuǎn)場相關(guān)(下一篇會講解)
- (nonnull UICollectionViewTransitionLayout *)collectionView:(UICollectionView *)collectionView transitionLayoutForOldLayout:(UICollectionViewLayout *)fromLayout newLayout:(UICollectionViewLayout *)toLayout;
UICollectionViewFlowLayout && UICollectionViewLayout:
UICollectionView之所以比UITableView強大丽惭,主要在于其精髓UICollectionViewLayout的布局击奶。它通過 UICollectionViewLayoutAttributes 類來管理 cell 、 Supplementary View 和 Decoration View 的 位置 责掏、 transform 柜砾、 alpha 、 hidden 等等换衬。先看看系統(tǒng)為我們提供的UICollectionViewFlowLayout布局的使用吧痰驱。
UICollectionViewFlowLayout 的常用屬性
//決定了每行的間隔
@property (nonatomic) CGFloat minimumLineSpacing;
//決定了Item之間的間隔
@property (nonatomic) CGFloat minimumInteritemSpacing;
//cell的大小(如果實現(xiàn)的代理該設(shè)置無效)
@property (nonatomic) CGSize itemSize;
//cell大小的預計算
@property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0); // defaults to CGSizeZero - setting a non-zero size enables cells that self-size via -preferredLayoutAttributesFittingAttributes:
//布局的方向
@property (nonatomic) UICollectionViewScrollDirection scrollDirection; // default is UICollectionViewScrollDirectionVertical
//頭視圖跟尾視圖的大型帧(橫向的時候担映,headerReferenceSize.width有效,headerReferenceSize.height無效叫潦∮辏縱向時相反)
@property (nonatomic) CGSize headerReferenceSize;
@property (nonatomic) CGSize footerReferenceSize;
//間距
@property (nonatomic) UIEdgeInsets sectionInset;
// Set these properties to YES to get headers that pin to the top of the screen and footers that pin to the bottom while scrolling (similar to UITableView).
@property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
@property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
UICollectionViewFlowLayout 的代理方法
//基本就是上面的屬性通過代理的方法返回
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;