UICollectionView(二)實現一個最簡單的UICollectionView
UICollectionView的學習可以對比著UITableView來,因為這兩個類很相似,實現途徑也很相似。它們都是datasource和delegate設計模式的:datasource為view提供資料來源,告訴view要顯示些什麼東西以及如何顯示它們,delegate提供一些樣式的小細節以及使用者互動的相應。
UICollectionViewDataSource
numberOfSectionsInCollectionView
//section的數量numberOfItemsInSection
//每個section對應的items的數量cellForItemAtIndexPath
//對應每個位置的item應該如何顯示viewForSupplementaryElementOfKind
//對應每組section的Supplementary View應該如何顯示
對於Decoration Views,提供方法並不在UICollectionViewDataSource中,而是直接UICollectionViewLayout類中的(因為它僅僅是檢視相關,而與資料無關)。UICollectionViewDelegate
資料無關的view的外形啊,使用者互動啊什麼的,由UICollectionViewDelegate來負責:
- cell的高亮
- cell的選中狀態
- 可以支援長按後的選單
關於使用者互動,UICollectionView也做了改進。每個cell現在有獨立的高亮事件和選中事件的delegate,使用者點選cell的時候,現在會按照以下流程向delegate進行詢問:-collectionView:shouldHighlightItemAtIndexPath:
是否應該高亮?-collectionView:didHighlightItemAtIndexPath:
如果1回答為是,那麼高亮-collectionView:shouldSelectItemAtIndexPath:
無論1結果如何,都詢問是否可以被選中?-collectionView:didUnhighlightItemAtIndexPath:
如果1回答為是,那麼現在取消高亮-collectionView:didSelectItemAtIndexPath:
如果3回答為是,那麼選中cell
狀態控制要比以前靈活一些,對應的高亮和選中狀態分別由highlighted和selected兩個屬性表示。
- 關於Cell
相對於UITableViewCell來說,UICollectionViewCell沒有這麼多花頭。首先UICollectionViewCell不存在各式各樣的預設的style,這主要是由於展示物件的性質決定的,因為UICollectionView所用來展示的物件相比UITableView來說要來得靈活,大部分情況下更偏向於影像而非文字,因此需求將會千奇百怪。因此SDK提供給我們的預設的UICollectionViewCell結構上相對比較簡單,由下至上:
首先是cell本身作為容器view
然後是一個大小自動適應整個cell的backgroundView,用作cell平時的背景
再其上是selectedBackgroundView,是cell被選中時的背景
-
最後是一個contentView,自定義內容應被加在這個view上
這次Apple給我們帶來的好康是被選中cell的自動變化,所有的cell中的子view,也包括contentView中的子view,在當cell被選中時,會自動去查詢view是否有被選中狀態下的改變。比如在contentView里加了一個normal和selected指定了不同圖片的imageView,那麼選中這個cell的同時這張圖片也會從normal變成selected,而不需要額外的任何程式碼。
-
關於重用
為了得到高效的View,對於cell的重用是必須的,避免了不斷生成和銷燬物件的操作,這與在UITableView中的情況是一致的。但值得注意的時,在UICollectionView中,不僅cell可以重用,Supplementary View和Decoration View也是可以並且應當被重用的。在iOS5中,Apple對UITableView的重用做了簡化,以往要寫類似這樣的程式碼:UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MY_CELL_ID"]; if (!cell) { //如果沒有可重用的cell,那麼生成一個 cell = [[UITableViewCell alloc] init]; } //配置cell,blablabla return cell
而如果我們在TableView向資料來源請求資料之前使用-registerNib:forCellReuseIdentifier:
方法為@“MY_CELL_ID"註冊過nib的話,就可以省下每次判斷並初始化cell的程式碼,要是在重用佇列裡沒有可用的cell的話,runtime將自動幫我們生成並初始化一個可用的cell。
這個特性很受歡迎,因此在UICollectionView中Apple繼承使用了這個特性,並且把其進行了一些擴充套件。使用以下方法進行註冊:
- -registerClass:forCellWithReuseIdentifier:
- -registerClass:forSupplementaryViewOfKind:withReuseIdentifier:
- -registerNib:forCellWithReuseIdentifier:
- -registerNib:forSupplementaryViewOfKind:withReuseIdentifier:
相比UITableView有兩個主要變化:一是加入了對某個Class的註冊,這樣即使不用提供nib而是用程式碼生成的view也可以被接受為cell了;二是不僅只是cell,Supplementary View也可以用註冊的方法繫結初始化了。在對collection view的重用ID註冊後,就可以像UITableView那樣簡單的寫cell配置了:
- (UICollectionView)collectionView:(UICollectionView)cv cellForItemAtIndexPath:(NSIndexPath*)indexPath {
MyCell *cell = [cv dequeueReusableCellWithReuseIdentifier:@”MY_CELL_ID”]; // Configure the cell's content
cell.imageView.image = ...
return cell;
}
需要吐槽的是,對collection view,取重用佇列的方法的名字和UITableView裡面不一樣了,在Identifier前面多加了Reuse五個字母,語義上要比以前清晰,命名規則也比以前嚴謹了..不知道Apple會不會為了追求完美而把UITableView中的命名不那麼好的方法deprecate掉。
- UICollectionViewLayout
終於到UICollectionView的精髓了。這也是UICollectionView和UITableView最大的不同。UICollectionViewLayout可以說是UICollectionView的大腦和中樞,它負責了將各個Cell、Supplementary View和Decoration Views進行組織,為它們設定各自的屬性,包括但不限於:
- 位置
- 尺寸
- 透明度
- 層級關係
- 形狀
- 等等等等…
Layout決定了UICollectionView是如何顯示在介面上的。在展示之前,一般需要生成合適的UICollectionViewLayout子類物件,並將其賦予CollectionView的collectionViewLayout屬性。
Apple為我們提供了一個最簡單可能也是最常用的預設layout物件: UICollectionViewFlowLayout。Flow Layout簡單說是一個直線對齊的layout。
**itemSize**
首先一個重要的屬性是itemSize,它定義了每一個item的大小。通過設定itemSize可以全域性地改變所有cell的尺寸,如果想要對某個cell制定尺寸,可以使用-collectionView:layout:sizeForItemAtIndexPath:方法。
@property (nonatomic) CGSize itemSize;
-collectionView:layout:sizeForItemAtIndexPath:
**間隔**
可以指定item之間的間隔和每一行之間的間隔,和size類似,有全域性屬性,也可以對每一個item和每一個section做出設定:
@property (CGSize) minimumInteritemSpacing
@property (CGSize) minimumLineSpacing
-collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
-collectionView:layout:minimumLineSpacingForSectionAtIndex:
**滾動方向**
由屬性scrollDirection確定scroll view的方向,將影響Flow Layout的基本方向和由header及footer確定的section之間的寬度
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;
**Header和Footer尺寸**
同樣地分為全域性和部分。需要注意根據滾動方向不同,header和footer的高和寬中只有一個會起作用。垂直滾動時section間寬度為該尺寸的高,而水平滾動時為寬度起作用。
@property (CGSize) headerReferenceSize
@property (CGSize) footerReferenceSize
-collectionView:layout:referenceSizeForHeaderInSection:
-collectionView:layout:referenceSizeForFooterInSection:
**縮排**
@property UIEdgeInsets sectionInset;
-collectionView:layout:insetForSectionAtIndex:
總結
一個UICollectionView的實現包括兩個必要部分:UICollectionViewDataSource和UICollectionViewLayout,和一個互動部分:UICollectionViewDelegate。而Apple給出的UICollectionViewFlowLayout已經是一個很強力的layout方案了。
相關文章
- UICollectionView 簡單介紹UIView
- UICollectionView(一)簡介UIView
- iOS UICollectionView的簡單使用和常用代理方法iOSUIView
- UICollectionViewUIView
- UICollectionView自定義佈局(二)UIView
- UICollectionView使用UIView
- UICollectionView(一)——整體總結UIView
- 使用UICollectionView實現首頁的滾動效果UIView
- iOS開發UI篇--使用UICollectionView實現一個傾斜列表效果iOSUIView
- 五個UICollectionView常用的知識點UIView
- UICollectionView自定義佈局(一)UIView
- iOS開發UI篇--使用UICollectionView實現一個列表頭部拉伸效果的案例iOSUIView
- UICollectionView間隙的坑UIView
- UICollectionView 瀑布流的使用UIView
- UITableView/UICollectionView使用技巧UIView
- iOS之UICollectionView的快速使用iOSUIView
- iOS專案開發實戰——使用UICollectionView實現瀑布流iOSUIView
- 自己實現一個最簡單的資料庫資料庫
- iOS中使用UICollectionView的細節iOSUIView
- UICollectionView SelectItem方法無效的原因UIView
- iOS UICollectionView那些我”錯過”的APIiOSUIViewAPI
- 使用ABAP實現一個最簡單的區塊鏈原型區塊鏈原型
- C#實現一個最簡單的HTTP伺服器C#HTTP伺服器
- 【iOS】關於 UICollectionView 的自定義佈局iOSUIView
- [iOS]自定義UICollectionView 2-1–CollectionView的實現(定義與初始化)iOSUIView
- 最簡單的web伺服器實現(一)Web伺服器
- 實現一個簡單版本的vue及原始碼解析(二)Vue原始碼
- iOS UICollectionView 橫向分頁佈局iOSUIView
- 關於一個最簡單的數獨解題實現與疑惑一
- iOS Swift UICollectionView橫向分頁的問題iOSSwiftUIView
- UICollectionView: 糊一張裝飾檢視 Decoration View 的一點經驗UIView
- websocket+node實現一個最簡單的即時通訊功能Web
- php實現一個簡單的socketPHP
- 實現一個簡單的TomcatTomcat
- 實現一個簡單的 RESTful APIRESTAPI
- 實現一個簡單的模板引擎
- 實現一個簡單的 dd 庫
- 自己實現一個簡單的 PromisePromise