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