iOS使用UICollectionView實現(xiàn)瀑布流

原文地址:http://www.reibang.com/p/040c824736cd

UICollectionView實現(xiàn)瀑布流

在iOS中可以實現(xiàn)瀑布流的目前已知的有2種方案:

使用UIScrollView自己封裝一套佳魔,這種方案是應用于iOS6之前的曙聂,因為iOS6才出來UICollectionView,不過現(xiàn)在這種方案已經(jīng)不怎么用了,還得自己封裝鞠鲜。而且自己封裝的性能不一定有系統(tǒng)的要好宁脊。

使用系統(tǒng)自帶的UICollectionView,然后自定義layout贤姆,自己實現(xiàn)瀑布流效果

本文中我們介紹第二種實現(xiàn)方案

首先我們需要自定義一個繼承于UICollectionViewLayout的layout榆苞,然后需要重寫四個方法:

(void)prepareLayout

(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

(UICollectionViewLayoutAttributes)layoutAttributesForItemAtIndexPath:(NSIndexPath)indexPath

(CGSize)collectionViewContentSize

第一個方法是做一些初始化的操作,這個方法必須先調(diào)用一下父類的實現(xiàn)

第二個方法返回的是一個裝著UICollectionViewLayoutAttributes的數(shù)組

第三個方法返回indexPath位置的UICollectionViewLayoutAttributes

第四個方法是返回UICollectionView的可滾動范圍

如何實現(xiàn)瀑布流

首先我們需要明白一點瀑布流的排列霞捡,瀑布流是大小不規(guī)則的一些控件分布在手機屏幕上面坐漏,然后肯定有長度高的也有矮的(就像人的身高一樣,哈哈哈)碧信,當排滿第一排的時候就會往下繼續(xù)排赊琳,那么這個應該往哪里放呢,==答案就是把它放到第一排最短的那個下面==砰碴,以此類推躏筏,按照這個規(guī)律排列下去。

明白了這一點我們接下來就該寫代碼了

首先我們創(chuàng)建兩個數(shù)組一個裝著cell的布局屬性呈枉,另一個裝著當前cell的總高度

//c存放所有cell的布局屬性@property(nonatomic,strong)NSMutableArray*attrsArray;//存放所有列的當前高度@property(nonatomic,strong)NSMutableArray*columnHeights;/** 內(nèi)容的高度 */@property(nonatomic,assign)CGFloatcontentHeight;

- (void)prepareLayout{? ? [superprepareLayout];self.contentHeight =0;//清除之前計算的所有高度趁尼,因為刷新的時候回調(diào)用這個方法[self.columnHeights removeAllObjects];for(NSIntegeri =0; i < DefaultColumnCpunt; i++) {? ? ? ? [self.columnHeights addObject:@(self.edgeInsets.top)];? ? }//把初始化的操作都放到這里[self.attrsArray removeAllObjects];//開始創(chuàng)建每一個cell對應的布局屬性NSIntegercount = [self.collectionView numberOfItemsInSection:0];for(NSIntegeri =0; i < count; i++) {// 創(chuàng)建位置NSIndexPath*indexPath = [NSIndexPathindexPathForItem:i inSection:0];// 獲取indexPath位置cell對應的布局屬性UICollectionViewLayoutAttributes*attrs = [selflayoutAttributesForItemAtIndexPath:indexPath];? ? ? ? [self.attrsArray addObject:attrs];? ? }}

首先把cell的高度設(shè)置為self.edgeInsets.top不然這里會崩潰。然后取出來item的個數(shù)猖辫,然后循環(huán)取出每個item的UICollectionViewLayoutAttributes弱卡,然后把它加入到attsArray,然后在- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect這個方法中直接返回attrsArray即可住册。

- (UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath*)indexPath{UICollectionViewLayoutAttributes*attrs = [UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:indexPath];CGFloatcollectionViewW =self.collectionView.frame.size.width;CGFloatw = (collectionViewW -self.edgeInsets.left -self.edgeInsets.right -(self.columnCount -1) *self.columnMargin) /self.columnCount;CGFloath = [self.delegate WaterFlowLayout:selfheightForRowAtIndexPath:indexPath.item itemWidth:w];NSIntegerdestColumn =0;CGFloatminColumnHeight = [self.columnHeights[0] doubleValue];for(NSIntegeri =0; i columnHeight) {? ? ? ? ? ? minColumnHeight = columnHeight;? ? ? ? ? ? destColumn = i;? ? ? ? }? ? }CGFloatx =self.edgeInsets.left + destColumn * (w +self.columnMargin);CGFloaty = minColumnHeight;if(y !=self.edgeInsets.top) {? ? ? ? y +=self.rowMargin;? ? }? ? attrs.frame =CGRectMake(x, y, w, h);self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));CGFloatcolumnHeight = [self.columnHeights[destColumn] doubleValue];if(self.contentHeight < columnHeight) {self.contentHeight = columnHeight;? ? }returnattrs;}

上面這個方法是計算item的位置的代碼,首先取出來indexPath的UICollectionViewLayoutAttributes對象瓮具,然后取出來w荧飞,h,核心代碼如下:

NSIntegerdestColumn =0;CGFloatminColumnHeight = [self.columnHeights[0] doubleValue];for(NSIntegeri =0; i columnHeight) {? ? ? ? ? ? minColumnHeight = columnHeight;? ? ? ? ? ? destColumn = i;? ? ? ? }? ? }CGFloatx =self.edgeInsets.left + destColumn * (w +self.columnMargin);CGFloaty = minColumnHeight;if(y !=self.edgeInsets.top) {? ? ? ? y +=self.rowMargin;? ? }

首先弄了一個標示destColumn來做記錄是那一列的名党,然后定義一個minColumnHeight為最小的列的高度叹阔,取出來self.columnHeights[0]的高度,這里默認為它就是最小的传睹,然后進行for循環(huán)遍歷耳幢,取出來i位置上面的高度,如果這個值小于之前的minColumnHeight,那么取出來的這個高度就是最小的高度了睛藻,然后把i的值賦值給destColumn启上,然后x的值就是上面代碼中的相加的結(jié)果,y的值就是繼續(xù)加上間距

- (CGSize)collectionViewContentSize{//? ? CGFloat maxColumnHeight = [self.columnHeights[0] doubleValue];////? ? for (NSInteger i = 1; i < DefaultColumnCpunt; i++) {//? ? ? ? // 取得第i列的高度//? ? ? ? CGFloat columnHeight = [self.columnHeights[i] doubleValue];////? ? ? ? if (maxColumnHeight < columnHeight) {//? ? ? ? ? ? maxColumnHeight = columnHeight;//? ? ? ? }//? ? }returnCGSizeMake(0,self.contentHeight +self.edgeInsets.bottom);}

代碼在github上面

github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末店印,一起剝皮案震驚了整個濱河市冈在,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌按摘,老刑警劉巖包券,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異炫贤,居然都是意外死亡溅固,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門兰珍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侍郭,“玉大人,你說我怎么就攤上這事俩垃±祝” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵口柳,是天一觀的道長苹粟。 經(jīng)常有香客問我,道長跃闹,這世上最難降的妖魔是什么嵌削? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮望艺,結(jié)果婚禮上苛秕,老公的妹妹穿的比我還像新娘。我一直安慰自己找默,他們只是感情好艇劫,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惩激,像睡著了一般店煞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上风钻,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天顷蟀,我揣著相機與錄音,去河邊找鬼骡技。 笑死鸣个,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播囤萤,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼昼窗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了阁将?” 一聲冷哼從身側(cè)響起膏秫,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎做盅,沒想到半個月后缤削,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡吹榴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年亭敢,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片图筹。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡帅刀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出远剩,到底是詐尸還是另有隱情扣溺,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布瓜晤,位于F島的核電站锥余,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痢掠。R本人自食惡果不足惜驱犹,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望足画。 院中可真熱鬧雄驹,春花似錦、人聲如沸淹辞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽象缀。三九已至彬向,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間攻冷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工遍希, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留等曼,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像禁谦,于是被迫代替她去往敵國和親胁黑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容