1.viewcontroller Setting CollectionView layout information
Import Uikit
Import Sdwebimage
Import Mjrefresh
Class Yfwaterfallviewcontroller:uiviewcontroller,uicollectionviewdatasource,uicollectionviewdelegate, uicollectionviewdelegateflowlayout,yfwaterfalllayoutdelegate {
Let Cellid = "Waterid"
var datalists =array<yfvideoinfo> ()
var collectionview:uicollectionview!
Let header =mjrefreshnormalheader ()//Top Refresh
Let footer =mjrefreshautonormalfooter ()//Bottom Refresh
Overridefunc Viewdidload () {
Super.viewdidload ()
Self.view.backgroundColor =uicolor.whitecolor ()
Self.navigationItem.title = "Waterfall Flow"
Let Layout:yfwaterfallcollectionlayout =yfwaterfallcollectionlayout ()
Layout.delegate =self
Self.collectionview =uicollectionview (Frame:cgrectmake (0,0,screenwidth,screenheight), CollectionViewLayout: Layout
Collectionview.datasource =self
Collectionview.backgroundcolor =uicolor.lightgraycolor ()
Collectionview.registerclass (yfwaterfallcollectionviewcell.self, Forcellwithreuseidentifier:cellid)
Header.setrefreshingtarget (Self, refreshingaction: #selector (Yfwaterfallviewcontroller.headerrefresh))
Collectionview.mj_header =header
Footer.setrefreshingtarget (Self, refreshingaction: #selector (Yfwaterfallviewcontroller.footerrefresh))
Collectionview.mj_footer =footer
Self.view.addSubview (CollectionView)
Self.loaddata ()
}
Func Headerrefresh () {
Self.datalists = [Yfvideoinfo] ()
Self.loaddata ()
}
Func Footerrefresh () {
Self.loaddata ()
}
Data loading process
Func LoadData () {
var params:dictionary<string,string> = [:]
params["Sign"] =swsign
Yfhttptool.post ("http://...", Parameters:params, Success: {(operation, responseobject) in
Yfalertview.hidehud (Self.view)
If Responseobject? Objectforkey ("status") as! NSNumber ==1 {
Let Tmparray:nsarray = responseobject!. Objectforkey ("info") as! Nsarray
For Dictin Tmparray {
Let Model:yfvideoinfo =yfvideoinfo.ljbobjectwithdict (dictas! Dictionary)
Let sizedict = Dict.objectforkey ("Imgsize")
MODEL.W = sizedict!. Objectforkey ("width") as? NSNumber
Model.h = sizedict!. Objectforkey ("height") as? NSNumber
Self.dataLists.append (model)
}
Self.collectionView.reloadData ()
Self.collectionView.mj_header.endRefreshing ()
Self.collectionView.mj_footer.endRefreshing ()
} else {
Yfalertview.showerrortext ("Query failed!", View:self.view)
}
}) {(operation, error) in
Print ("Error:\ (Error)")
Yfalertview.hidehud (Self.view)
Yfalertview.showerrortext ("Network connection Exception!", View:self.view)
}
}
CollectionView Data Source Settings
Func CollectionView (Collectionview:uicollectionview, numberofitemsinsection section:int)-> Int {
Returnself.dataLists.count
}
Give the layout height, according to the proportional calculation
Func CollectionView (Collectionview:uicollectionview, Cellforitematindexpath Indexpath:nsindexpath)-> Uicollectionviewcell {
Let Cell:yfwaterfallcollectionviewcell = Collectionview.dequeuereusablecellwithreuseidentifier (Self.cellID, Forindexpath:indexpath) as! Yfwaterfallcollectionviewcell
Cell.model =self.datalists[indexpath.row]
return cell
}
Layout Agent
Func waterfalllayout (Layout:uicollectionviewflowlayout, Index:nsinteger, width:cgfloat)-> CGFloat {
Let Model:yfvideoinfo =self.datalists[index]
Return width/(cgfloat (MODEL.W?). Floatvalue)! /CGFloat (model.h?. Floatvalue))
}
Func columncountofwaterfalllayout (layout:uicollectionviewflowlayout)->nsinteger {
Return2
}
Overridefunc didreceivememorywarning () {
Super.didreceivememorywarning ()
}
}
2.cell set, layoutsubviews to prevent dislocation
Import Uikit
Class Yfwaterfallcollectionviewcell:uicollectionviewcell {
Initialize item data when data is assigned
var model:yfvideoinfo? {
Didset {
Let URL =nsurl (string: "Http://xxx.xxx.cn\" (model!). Videoimgurl) ")
Self.imageView.sd_setImageWithURL (URL)
}
}
Let Imageview:uiimageview =uiimageview ()
Overrideinit (Frame:cgrect) {
Super.init (Frame:frame)
Self.imageView.frame =cgrectmake (0,0, Frame.size.width, Frame.size.height)
Self.addsubview (Self.imageview)
}
Requiredinit? (Coder Adecoder:nscoder) {
FatalError ("Init (coder:) has not been implemented")
}
Re-layout, or two times refresh due to cell reuse causes dislocation
Overridefunc Layoutsubviews () {
Super.layoutsubviews ()
Self.imageView.frame =cgrectmake (0,0,self.frame.size.width,self.frame.size.height)
}
}
3. Custom Uicollectionviewflowlayout Class
Import Uikit
Protocol Yfwaterfalllayoutdelegate {
Returns the height of item at index position
Func waterfalllayout (layout:uicollectionviewflowlayout,index:nsinteger,width:cgfloat)->CGFloat
Returns the number of columns displayed by the waterfall stream
Func columncountofwaterfalllayout (layout:uicollectionviewflowlayout)->nsinteger
}
Class Yfwaterfallcollectionlayout:uicollectionviewflowlayout {
var delegate:yfwaterfalllayoutdelegate?
var attributesarray = [Uicollectionviewlayoutattributes]//Layout information store to prevent the Drop-down from seeing two of times, returning layout information multiple times.
var columnheights =array<float> ()//stores the height information for the column in the current row.
var columncount:int =2//default number of columns
var edgeinsets:uiedgeinsets =uiedgeinsets (Top:5, Left:5, Bottom:5, Right:5)
var columnmargin:cgfloat =5//column Spacing
var rowmargin:cgfloat =5//Line Spacing
Overridefunc Preparelayout () {
Super.preparelayout ()
Initializing the maximum height data collection
Columnheights =array<float> ()
Self.columncount = (self.delegate?) Columncountofwaterfalllayout (self))!
Ifself.columncount <=0 {
Return
}
For_in0.. <columncount {
Columnheights.append (Float (self.edgeInsets.top))
}
Initializing the layout information data source
Attributesarray = [Uicollectionviewlayoutattributes] ()
Let Cellcount =self.collectionview!. Numberofitemsinsection (0)
For Iin0.. <cellcount {
Let Indexpath = Nsindexpath (foritem:i, insection:0)
Let attributes =self.layoutattributesforitematindexpath (Indexpath)
Attributesarray.append (attributes!)
}
}
All cell Position Properties
Overridefunc Layoutattributesforelementsinrect (Rect:cgrect)
-> [Uicollectionviewlayoutattributes]? {
Returnself.attributesarray
}
This method returns the position and size of each cell
Overridefunc Layoutattributesforitematindexpath (indexpath:nsindexpath)-> uicollectionviewlayoutattributes? {
Let attribute =uicollectionviewlayoutattributes (Forcellwithindexpath:indexpath)
Let Collectionviewwidth:cgfloat =self.collectionview!. Frame.size.width
Let Width:cgfloat = (Collectionviewwidth-self.edgeinsets.left-self.edgeinsets.right-(CGFloat (Self.columnCount)-1) * self.columnmargin)/cgfloat (Self.columncount);
Calculates the current item should be placed in the first column (calculate which column height is the shortest)
var mincolumn:int =0//default is the No. 0 column
var minheight:float =maxfloat
Traverse to find the smallest height of the column, added below the smallest column.
for (Index,value) inself.columnHeights.enumerate () {
If MinHeight > value {
MinHeight = value
Mincolumn = Index
}
}
Let X:cgfloat =self.edgeinsets.left +cgfloat (mincolumn) * (width +self.columnmargin)
Let Y:cgfloat =cgfloat (minheight) +self.rowmargin
Let Height:cgfloat = (self.delegate?.) Waterfalllayout (self, Index:indexPath.row, width:width))!
Attribute.frame =cgrectmake (x, y, width, height)
Update the height of the shortest column in the array
Self.columnheights[mincolumn] =float (y + height)
return attribute
}
&nbs