collectionview實現以下效果.
思路:
先說一下這個效果的實現思路,首先需要確定該瀑布流有多少列,然後需要確定每個cell 的高度,用乙個陣列記錄下每一列的已新增上去的cell的高度和.然後新增下乙個cell的時候找出所有列中高度最小的列,再新增上去.
例如:在該例子中,總共有兩列,當新增完第一第二個cell,即第一行新增完了,要新增第三個cell,就需要找出第一第二列中高度最短的那一列,然後新增到最短那一列下面,以此類推.
實現:
首先我們需要初始化collectionview,步驟與 「ios-collectionview 基礎」 類似.
該效果需要自定義布局,實現瀑布流效果.
建立乙個布局類,繼承於uicollectionviewlayout. (流水布局對應的類繼承於uicollectionviewflowlayout, uicollectionviewflowlayout 是 uicollectionviewlayout的子類)
在布局類需要重寫四個方法,分別是:
-作用:在這個方法做一些初始化操作
-注意:一定要呼叫 [super preparelayout]
-作用:返回indexpath 位置cell對應的布局屬性
-作用:
這個方法的返回值是個陣列
這個陣列中存放的是uicollectionviewlayoutattributes物件
uicollectionviewlayoutattributes 物件決定了cell的排布方式
-作用:決定collectionview的可滾動範圍
**實現:
布局類.m 檔案
1.定義如下靜態變數
/** 列數*/
static
const cgfloat columcount = 3;
/** 每一列間距*/
static
const cgfloat colummargin = 10;
/** 每一列間距*/
static
const cgfloat rowmargin = 10;
/** 邊緣間距*/
static
const uiedgeinsets defaultedgeinsets = ;
2.宣告兩個屬性
/** 布局屬性陣列*/
@property (nonatomic,strong) nsmutablearray *attrsarray;
/** 存放所有列的當前高度*/
@property (nonatomic,strong) nsmutablearray *columnheight;
懶載入 attrsarray, columnheight
- (nsmutablearray *)attrsarray
return _attrsarray;
}- (nsmutablearray *)columnheight
return _columnheight;
}
重寫preparelayout方法
/** 初始化*/
- (void)preparelayout
nsinteger count = [self
.collectionview numberofitemsinsection:0];
[self
.attrsarray removeallobjects];
for (nsinteger i = 0; i < count; i++)
}
該方法返回對應cell上的布局屬性.我們可以在這個方法中設定cell 的布局樣式.在preparelayout方法中,我們根據這個方法,傳入對應的indexpath從而獲取到布局屬性attr,然後新增到陣列中.
/**
* 返回indexpath 位置cell對應的布局屬性
*/- (uicollectionviewlayoutattributes *)layoutattributesforitematindexpath:(nsindexpath *)indexpath
}cgfloat w = (self
.collectionview
.frame
.size
.width - self
.defaultedgeinsets
.left - self
.defaultedgeinsets
.right - (self
.columcount - 1) * self
.colummargin )/self
.columcount;
//(使用**在外部決定cell 的高度,下面會介紹)
cgfloat h = [self
.delegate waterflowlayout:self heightforrowatindex:indexpath.item itemwidth:w];
cgfloat x = self
.defaultedgeinsets
.left + destcolumn*(w + self
.colummargin);
cgfloat y = mincolumnheight ;
if (y != self
.defaultedgeinsets
.top)
attr.frame = cgrectmake(x,y,w,h);
self
.columnheight[destcolumn] = @(y+ h);
return attr;
}
重寫layoutattributesforelementsinrect:方法
/**
* 決定cell 的排布
*/- (nsarray*)layoutattributesforelementsinrect:(cgrect)rect
決定collectionview的可滾動範圍
- (cgsize)collectionviewcontentsize
}return cgsizemake(0, maxheight+self
.defaultedgeinsets
.bottom);
}
到此,瀑布流的效果就出來了.
但是可以想到,這樣來搭建布局,瀑布流的列數,cell與cell之間的間距以及邊緣距就固定了,顯然這是不夠靈活的.我們應該要把這些引數拋給使用該布局的類去決定,這樣才是乙個通用的**.
來到布局類.h 檔案中,新增協議以及**
@class
waterflowlayout;
@protocol
waterflowlayoutdelegate
@required
//決定cell的高度,必須實現方法
- (cgfloat)waterflowlayout:(waterflowlayout *)waterflowlayout heightforrowatindex:(nsinteger)index itemwidth:(cgfloat)width;
@optional
//決定cell的列數
- (nsinteger)cloumncountinwaterflowlayout:(waterflowlayout *)waterflowlayout;
//決定cell 的列的距離
- (cgfloat)colummargininwaterflowlayout:(waterflowlayout *)waterflowlayout;
//決定cell 的行的距離
- (cgfloat)rowmargininwaterflowlayout:(waterflowlayout *)waterflowlayout;
//決定cell 的邊緣距
- (uiedgeinsets)edgeinsetinwaterflowlayout:(waterflowlayout *)waterflowlayout;
@end
@inte***ce
waterflowlayout : uicollectionviewlayout
/*****/
@property (nonatomic,assign) id
delegate;
- (nsinteger)columcount;
- (cgfloat)colummargin;
- (cgfloat)rowmargin;
- (uiedgeinsets)defaultedgeinsets;
@end
回到布局類.m檔案中,實現宣告的方法.在這裡需要明確,外部必須通過實現**給定cell的高度.另外,如果外部通過實現**給定列數、列間距、行間距、邊緣距就用給定的,否則使用預設的列數、列間距、行間距、邊緣距.
- (nsinteger)columcount
else
}- (cgfloat)colummargin
else
}- (cgfloat)rowmargin
else
}- (uiedgeinsets)defaultedgeinsets
else
}
到此,collectionview瀑布流框架搭建完成了!! 關於瀑布流
鑑於現今瀑布流的流行,上次面試的時候又遇到了這個問題,可我確實沒有實現過,一時問起確實只知道用float left的方式。1.固定列寬和列數,列設定float left,乙個列就是乙個內容塊,載入內容就選擇載入到各列中 2.使用css3的多列布局 前兩種方式比較簡單,而所謂最大的缺陷也就是列數目已確...
瀑布流函式
在jquery物件後面新增瀑布流函式 function 其他行 else 其他行 top 每列中的最小值 即最低的那一列 val css 修改高度陣列 最小高度 最小高度 當前子元素高度 arrheight minindex minheight height 查詢高度 最大值 var maxinde...
瀑布流處理
瀑布流就是用來解決展示時出現空白頁面的問題 這裡可以再前端頁面直接寫 2.js裡物件中,this 物件 再函式中,this window 注釋都寫在 裡,簡單明瞭 前端頁面 105西 modelsfrom django.db import models class img models.model ...