石工布局(Masonty Layout)是指集合視圖中的物件模仿石灰漿墻咱台,常用來在二維空間中平鋪大量物件屈嗤。
現(xiàn)在創(chuàng)建一個UICollectionViewLayout的子類并添加到工程中,布局子類中主要有兩個職責(zé)选浑,首先是計算集合視圖中每個物件的frame办素,其次是計算集合視圖整個內(nèi)容的大小。
子類需要覆蓋的方法:
1.- (void)prepareLayout欣尼;//布局之前被調(diào)用爆雹,在這個方法中計算所有item的frame
2.- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;//返回給定矩形中所有物件的屬性
3.- (CGSize)collectionViewContentSize; //返回集合視圖內(nèi)容的大小
在本例中愕鼓,物件的寬度應(yīng)該有兩個變量決定钙态,列數(shù)和item之間的間距,這種情況下菇晃,引入變量numberOfColums和itemSpacing册倒。物件的高度則由數(shù)據(jù)源提供一個變量,可以聲明一個委托對象磺送,在委托中驻子,聲明一個collectionView:Layout:heightForItemAtIndexPath:協(xié)議方法。
接下來就是計算每個item的frame估灿。
1.計算item的寬度
2.計算Item的x坐標
其中currentColumn為item所在的列拴孤。
3.計算item的y和高度
通過調(diào)用剛才寫的協(xié)議方法來的得到高度,在加上在這一列前面所有item的高度來得到y(tǒng)甲捏,這里使用了lastYValueForColum字典來維護了布局中所有列的高度演熟。
開始先從字典lastYValueForColumn中獲取y值,然后給y加上高度itemSpacing再保存到lastYValueForColumn中司顿。計算完成后芒粹,就保存到layoutInfo中,在下一個方法layoutAttributesForElementsInRect:中調(diào)用到layoutInfo大溜。當集合視圖滾動時化漆,系統(tǒng)會調(diào)用這個方法并傳遞可見的矩形區(qū)域。用CGRectIntersectsRect方法可以把這個區(qū)域中的item篩選出來钦奋,返回一個裝有這些item的數(shù)組座云。代碼實現(xiàn)如下:
接下來的任務(wù)就是計算集合視圖內(nèi)容的大小,y值已經(jīng)存在lastYValueForColumn字典中付材,我們擴遍歷這個字典中找到每列中最大y值作為集合視圖的contentSize的height朦拖。這個方法涉及到所有類型的視圖,也就是cell厌衔,supplementary views和decoration views璧帝。如果選擇忽略傳入的矩形,并且為collection view中的所有視圖返回布局屬性富寿。這將對性能產(chǎn)生非常壞的影響睬隶,特別是可見cell遠少于所有cell數(shù)量的時候锣夹,collection view和布局對象將會為那些不可見的視圖做額外不必要的工作。
最后苏潜,當 collection view 的 bounds 改變時银萍,布局需要告訴 collection view 是否需要重新計算布局。scroll view 的 bounds 在滾動時也會改變恤左,這意味著你的布局每秒會被丟棄多次贴唇。根據(jù)計算的復(fù)雜性判斷,這將會對性能產(chǎn)生很大的影響赃梧。
當 collection view 的寬度改變時滤蝠,我們自定義的布局必須被丟棄,但這滾動并不會影響到布局授嘀。collection view 將它的新 bounds 傳給shouldInvalidateLayoutForBoundsChange:方法物咳。這樣我們便能比較視圖當前的bounds 和新的 bounds 來確定返回值:
好了,小工告成蹄皱。喜歡的點個贊览闰,不喜歡的打賞幾塊吧。