應對復雜布局的瀑布流Layout
引
公司的項目中涉及到多列瀑布流、UITableView與sectionHeader的混合布局,之前的實現方式是以UITableView作為骨架,將帶有瀑布流的UICollectionView封裝到自定義的UITableViewCell中,但是出現的問題就是當cell中瀑布流的元素過多時,會出現明顯的卡頓,而且布局復雜,層次較多,難以維護。故而重新自定義了collectionView的Layout,在僅有一個collectionView的情況下完成了上述的布局。
這是我們項目.gif
更新:
2016-12-23
1、加入了collectionHeaderView,類似UITableView 中的 tableHeaderView
2、將 sideMargin 改為 sectionInsets,提高布局靈活度
項目基于Swift3.0~~
使用
閑話不多說,上代碼:
1、首先定義一個collectionview,并設置layout的代理:
let layout = ZJFlexibleLayout(delegate: self)
//如果需要有 headerView 的話,直接傳入即可,需提前設置frame
layout.collectionHeaderView = headerView
collectionView = UICollectionView(frame: kScreenBounds, collectionViewLayout: layout)
2、遵守對應的協議:
protocol ZJFlexibleLayoutDataSource: class{
//控制對應section的瀑布流列數
func numberOfCols(at section: Int) -> Int
//控制每個cell的尺寸,實際上就是獲取寬高比
func sizeOfItemAtIndexPath(at indexPath : IndexPath) -> CGSize
//控制瀑布流cell的間距
func spaceOfCells(at section: Int) -> CGFloat
//section 內邊距
func sectionInsets(at section: Int) -> UIEdgeInsets
//每個section的header尺寸
func sizeOfHeader(at section: Int) -> CGSize
//每個cell的額外高度
func heightOfAdditionalContent(at indexPath : IndexPath) -> CGFloat
}</code></pre>
協議詳解:
1.瀑布流列數
可以隨意設置瀑布流列數,如果是單列的話就相當于tableView了
func numberOfCols(at section: Int) -> Int
2.cell尺寸
這個應該不用多講吧,因為cell的寬度在列數確定時就已經算出來了,所以這個方法實質上是獲取cell的寬高比
func sizeOfItemAtIndexPath(at indexPath : IndexPath) -> CGSize

Paste_Image.png
3.cell間距
cell 的上下左右間距,注意不要跟sectionInsets搞混了
func spaceOfCells(at section: Int) -> CGFloat

Paste_Image.png
4.section 內邊距
這個是最近才加上的,可以讓每個section都有一個內邊距
func sectionInsets(at section: Int) -> UIEdgeInsets

Paste_Image.png
5.每個section的header尺寸
sectionHeader如果寬度小于屏寬,會自動居中
func sizeOfHeader(at section: Int) -> CGSize
6.cell的額外高度
此方法是專門公司項目的需求提出的,圖中標明的部分高度是不固定的,需要根據數據進行判斷
func heightOfAdditionalContent(at indexPath : IndexPath) -> CGFloat

Paste_Image.png
結束語
代碼寫的沒什么條理,所有東西都寫到一個文件里了(⊙﹏⊙)b,后續應該會用pod來管理

來自:http://www.jianshu.com/p/28eae0d82fdc