UICollectionView基本使用详解(OC)
概述
UICollectionView是從iOS6開始引入使用的,目前應(yīng)用非常廣泛,很牛逼!老外的博客也是這么說的(傳送門)
## 與UITableView的初步比較
- UITableView應(yīng)該是大家最熟悉的控件了,UICollectionView的使用與之類似,但又有所區(qū)別,如下介紹。
相同點(diǎn):- 1.都是通過datasource和delegate驅(qū)動(dòng)的(datasource和delegate官方文檔傳送),因此在使用的時(shí)候必須實(shí)現(xiàn)數(shù)據(jù)源與代理協(xié)議方法;
- 2.性能上都實(shí)現(xiàn)了循環(huán)利用的優(yōu)化。
- 1.UITableView的cell是系統(tǒng)自動(dòng)布局好的,不需要我們布局。但UICollectionView的cell是需要我們自己布局的。所以我們在創(chuàng)建UICollectionView的時(shí)候必須傳遞一個(gè)布局參數(shù),系統(tǒng)提供并實(shí)現(xiàn)了一個(gè)布局樣式:流水布局(UICollectionViewFlowLayout)(流水布局官方文檔傳送)。
- 注:蘋果關(guān)于FlowLayout的解析
- 2.UITableViewController的self.view == self.tableview;,但UICollectionViewController的self.view != self.collectionView;
- 3.UITableView的滾動(dòng)方式只能是垂直方向, UICollectionView既可以垂直滾動(dòng),也可以水平滾動(dòng);
- 4.UICollectionView的cell只能通過注冊來確定重用標(biāo)識(shí)符。
結(jié)論: 換句話說,UITableView的布局是UICollectionView的flow layout布局的一種特殊情況,類比于同矩形與正方形的關(guān)系
## 下面簡單介紹幾個(gè)基本用法(難度從低到高)
1. UICollectionView普通用法(FlowLayout布局)
- 上面我們提到了UICollectionView與UITableView的用法非常類似,下面就讓我們完全根據(jù)創(chuàng)建UITableView的方式來創(chuàng)建一個(gè)UICollectionView(請讀者類比UITableView的創(chuàng)建方式,實(shí)現(xiàn)數(shù)據(jù)源,代理等,這里就只提到與之不同的方面,詳細(xì)代碼可參考示例Demo)。
- 報(bào)錯(cuò)了,提示缺少布局參數(shù),如下:
- 解決報(bào)錯(cuò),我們可以傳FlowLayout參數(shù)方式,也可以重寫內(nèi)部init方法。我們這里采用重寫init方法,傳遞布局參數(shù)。這樣更加體現(xiàn)了封裝的思想,把傳遞布局參數(shù)封裝在CYXNormalCollectionViewController內(nèi),對外只提供統(tǒng)一的外部方法:init方法,代碼如下:
objc - (instancetype)init{ // 設(shè)置流水布局 UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init]; // UICollectionViewFlowLayout流水布局的內(nèi)部成員屬性有以下: /** @property (nonatomic) CGFloat minimumLineSpacing; @property (nonatomic) CGFloat minimumInteritemSpacing; @property (nonatomic) CGSize itemSize; @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 @property (nonatomic) CGSize headerReferenceSize; @property (nonatomic) CGSize footerReferenceSize; @property (nonatomic) UIEdgeInsets sectionInset; */ // 定義大小 layout.itemSize = CGSizeMake(100, 100); // 設(shè)置最小行間距 layout.minimumLineSpacing = 2; // 設(shè)置垂直間距 layout.minimumInteritemSpacing = 2; // 設(shè)置滾動(dòng)方向(默認(rèn)垂直滾動(dòng)) layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; return [self initWithCollectionViewLayout:layout]; } - 這里我們使用xib自定義cell,通過xib注冊cell的代碼如下
- 初步效果圖如下(這里就不詳細(xì)實(shí)現(xiàn)了,剩下請讀者參考UITableView的用法(請點(diǎn)這里))
2. 新手引導(dǎo)頁制作
- 簡述
- 新手引導(dǎo)頁,幾乎是每個(gè)應(yīng)用都有的,目的為了告訴用戶應(yīng)用的亮點(diǎn),達(dá)到吸引用戶的作用。
- 利用UICollectionView的優(yōu)勢(循環(huán)利用)實(shí)現(xiàn)新手引導(dǎo)頁,既簡單又高效,何樂而不為呢。
- 實(shí)現(xiàn)思路:
- 1.把UICollectionView的每個(gè)cell的尺寸設(shè)置為跟屏幕一樣大;
- 2.設(shè)置為水平滾動(dòng)方向,設(shè)置水平間距為0.
- 3.開啟分頁滾動(dòng)模式
- 以下是效果圖:
3. 圖片循環(huán)輪播器
- 請參考我之前的文章(內(nèi)附代碼)《iOS上機(jī)題(附個(gè)人見解)》
4. 帶特效的圖片瀏覽器(自定義布局/上)
以下內(nèi)容分為兩小節(jié):
1> Github例子分析
2> 自己實(shí)現(xiàn)一個(gè)小Demo
(1)Github例子分析
- 我們經(jīng)常在Github上看到一些關(guān)于CollectionView的cell切換的炫酷效果,下面我們來分析一下Github上的這個(gè)卡片切換帶3D動(dòng)畫Demo(RGCardViewLayout)
- 下面是效果圖
- 目錄結(jié)構(gòu)分析:目錄結(jié)構(gòu)一目了然,關(guān)鍵在于有一個(gè)自動(dòng)布局類(如圖所示),這個(gè)類繼承自UICollectionViewFlowLayout(我們可以猜到他使用的是默認(rèn)的流水布局),并重寫了- (void)prepareLayout、- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect等方法。我們試著把這個(gè)類里面的重載方法都注釋掉,得到的效果跟普通用法的效果一樣(這里就不截圖了)。由此可見,作者肯定在這些方法內(nèi)做了個(gè)性化的設(shè)置。
- 關(guān)鍵源碼分析:
- 首先我們看到,作者在- (void)prepareLayout方法內(nèi)做了對collectionView的初始化布局操作。因此我們可以斷定重寫此方法是用做初始化的(讀者可以嘗試修改,改變效果)。
接著這個(gè)- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect方法應(yīng)該是最重要的了,同理,我們先注釋掉里面?zhèn)€性化的設(shè)置,只留[super layoutAttributesForElementsInRect:rect],我們發(fā)現(xiàn)炫酷的3D效果沒有了。因此可以斷定此方法是給每個(gè)Cell做個(gè)性化設(shè)置的。
方法解析:
這個(gè)方法的返回值是一個(gè)數(shù)組(數(shù)組里面存放著rect范圍內(nèi)所有元素的布局屬性)
這個(gè)方法的返回值決定了rect范圍內(nèi)所有元素的排布方式(frame)
UICollectionViewLayoutAttributes *attrs;
1.一個(gè)cell對應(yīng)一個(gè)UICollectionViewLayoutAttributes對象
2.UICollectionViewLayoutAttributes對象決定了cell的frame
上面關(guān)鍵方法都已經(jīng)實(shí)現(xiàn)了,但是運(yùn)行發(fā)現(xiàn)并沒有我們想要的效果,CollectionViewCell并沒有實(shí)時(shí)發(fā)生形變。y因此我們還需要調(diào)用以下方法。
方法解析:
只要滾動(dòng)屏幕 就會(huì)調(diào)用 方法 -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
只要布局頁面的屬性發(fā)生改變 就會(huì)重新調(diào)用 -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 這個(gè)方法
(2)仿寫Demo
經(jīng)過上面對代碼的分析,我們可以簡單了解到自定義layout布局的基本實(shí)現(xiàn),下面就可以仿寫一個(gè)簡單的Demo了,效果圖如下。
參考代碼如下(詳細(xì)見Github)
5.瀑布流布局(自定義布局/下)
- 瀑布流布局在很多應(yīng)用中非常常見,效果圖如下:
實(shí)現(xiàn)思路(簡化)
- (1)繼承自UICollectionViewLayout;
- (2)幾個(gè)需要重載的方法:
關(guān)鍵計(jì)算代碼如下(詳細(xì)見Github)
/*** 返回indexPath位置cell對應(yīng)的布局屬性*/ - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {// 創(chuàng)建布局屬性UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];// collectionView的寬度CGFloat collectionViewW = self.collectionView.frame.size.width;// 設(shè)置布局屬性的frameCGFloat w = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnCount;CGFloat h = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:w];// 找出高度最短的那一列NSInteger destColumn = 0;CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];for (NSInteger i = 1; i < self.columnCount; i++) {// 取得第i列的高度CGFloat columnHeight = [self.columnHeights[i] doubleValue];if (minColumnHeight > columnHeight) {minColumnHeight = columnHeight;destColumn = i;}}CGFloat x = self.edgeInsets.left + destColumn * (w + self.columnMargin);CGFloat y = minColumnHeight;if (y != self.edgeInsets.top) {y += self.rowMargin;}attrs.frame = CGRectMake(x, y, w, h);// 更新最短那列的高度self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));// 記錄內(nèi)容的高度CGFloat columnHeight = [self.columnHeights[destColumn] doubleValue];if (self.contentHeight < columnHeight) {self.contentHeight = columnHeight;}return attrs; }6. 布局切換
- 蘋果已經(jīng)為我們想好了布局切換的快捷方式,只需要通過以下方法,即可實(shí)現(xiàn)。
附: 源碼github地址
轉(zhuǎn)載于:https://www.cnblogs.com/YX-zhuanzhu/p/5288057.html
總結(jié)
以上是生活随笔為你收集整理的UICollectionView基本使用详解(OC)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机导论alu的全名,计算机导论试题1
- 下一篇: 人工智能基础——什么是人工智能