UICollectionViewColltroller是IOS中用來展示數據集的視圖,功能強大,而且能實現的視覺豐富,這篇隨筆筆者就演示下UICollectionViewConlltroller簡單的使用,獻給同樣在編程之路前進的人。
首先來看看UIColletionViewController各種效果(素材來源百度)
UICollectionViewController 有三個非常重要的協議UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout
他們的作用分別是數據源,事件代理,視圖布局。下面我講在demo重一個個講述這三個協議的用法。
開始
UICollectionViewDataSource三個重要方法1,numberOfSectionsInCollectionView。2,(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 。3, (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
一,新建項目,然后將默認新建的stroryboard跟View刪除,配置項目設置Main interface為空,在AppDelegate添加代碼
UIWindow *window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]]; [window makeKeyAndVisible]; self.window = window; UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init]; YYHCollectionViewController *cc = [[YYHCollectionViewController alloc]initWithCollectionViewLayout:flowLayout]; self.window.rootViewController = cc;
注意對於alloc UICollectionViewController 必須要給一個UIConllectionViewFlowLayout對象,否則會報錯。
二,UICollectionViewControlelr雖然同UITableViewContrller都是同樣用來展示數據,但是人性化卻差的多。因為里面的Cell,HeadView,FootView都是沒有默認控件,換句話來說就是所有的控件都是需要你自己來自定義。
UICollectionViewController自定義Cell跟HeadView,FootView跟UITableViewContrller大大有區別,但是你只需要記得一個方法initFrame:(CGRect )frame,你自定義的控件所有都要從這個獲取。
新建一個Cell 繼承UICollectionView,
然后進行必要的輸出連接。
在.M文件中載initFrame函數
-(instancetype)initWithFrame:(CGRect)frame{ if(self = [super initWithFrame:frame]){ NSArray *array = [[NSBundle mainBundle] loadNibNamed:@"YYHCollectionViewCell" owner:self options:nil]; if(array.count < 1) return nil; if(![[array firstObject] isKindOfClass:[UICollectionViewCell class]]) return nil; self = [array firstObject]; } return self; }
目前為止自定義Cell已經完成。
三,展示數據
#pragma mark <UICollectionViewDataSource> //返回Secion數量 - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return self.radios.count; } //返回每個Section 下面的Cell數量 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { RadioList *list = self.radios[section]; return list.radios.count; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { YYHCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; RadioList *list = self.radios[indexPath.section]; Radio *radio = list.radios[indexPath.row]; cell.imageView.image = [UIImage imageNamed:radio.imgUrl]; cell.descLabel.text = radio.fmName; return cell; }
成果如下:
結果與我們自定義的有所差別,我們理想狀態下是一個UIImageView,一個UILabel。但是現在所展示卻只有UIImageView。
尋找問題的所在需要靠自己,編程就是一個不斷尋找問題,然后解決的問題。反復查找,我懷疑是Cell的frame問題,輸出fram查看
NSLog(@"%f",cell.frame.size.width); NSLog(@"%f",cell.frame.size.height); 2016-01-19 19:13:46.040 UICollectionViewControllerDemo[3260:90515] 50.000000 2016-01-19 19:13:46.041 UICollectionViewControllerDemo[3260:90515] 50.000000
發現與XIB大小不符合,得出結果Frame問題(xib.size = {75,90}
從這里我們引出UICollectionViewFlowLayout
UICollectionViewFlowLayout
//Cell大小 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath; //Cell 空隙 - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section; //Cell 之間的間隔 - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section; //Secion之間的間隔 - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section; //ReuseHeadView 大小 - (CGSize)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section; //ReuseFootHead大小 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
以上的方法都是用來布局UICollectionView。
這里我選擇
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;來解決我的Cell顯示不完整的問題
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{ CGSize size = {75,90}; return size; }
結果如期:
但是其實我們的是需要展示分組的情況, ,那么接着我們就實現分組的情況
四,實現分組。其實UICollectionViewController分組關鍵就是Section>1,事實上我們已經分組,其實UI沒有合理顯示,如果讓它合理顯示呢?那就是添加ReuseHeadView
新建文件繼承UICollectionReuseView
同樣需要在.M文件重載initFrame方法
-(instancetype)initWithFrame:(CGRect)frame{ if(self = [super initWithFrame:frame]) { NSArray *arrary = [[NSBundle mainBundle] loadNibNamed:@"RadioCollectionReusableView" owner:self options:nil]; if(arrary.count < 1) return nil; if(![[arrary firstObject] isKindOfClass:[UICollectionReusableView class]]) return nil; self = [arrary firstObject]; } return self; }
到這里就完成了自定義HeadView
五,展示HeadView
添加代碼
//實現HeadView -(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{ RadioCollectionReusableView *headView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:reuseIdentifierForHeadView forIndexPath:indexPath]; if([kind isKindOfClass:[UICollectionElementKindSectionHeader class]]){ RadioList *list = self.radios[indexPath.section]; headView.descLabel.text = list.name; } return headView; } //headView大小 -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{ CGSize currentSize = [[UIScreen mainScreen] bounds].size; CGSize headSize = {currentSize.width,45}; return headSize; }
結果展示:
補充:自定義的cell跟headView是需要向CollectionViewController注冊
[self.collectionView registerClass:[YYHCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier]; [self.collectionView registerClass:[RadioCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:reuseIdentifierForHeadView];
UICollectionViewControllerDelegate,就簡單描述下里面的方法的作用
//Cell是否應該高亮 - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath; //Cell是否可以被選中 - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath; //Cell是否可以取消選中 - (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath; //Cell選中時候調用 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath; //Cell被取消選中調用 - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath;
隨便到這就結束了,不足之處還希望多多指教
附帶Demo:http://download.csdn.net/detail/q13432502528/9410574