swift瀑布流自定义布局实现

demo github下载地址

https://github.com/liwei5bao/SwiftWaterfallProject

//  ViewController.swift

//  SwiftWaterfall

import UIKit


import UIKit


class ViewController:UIViewController{

    

   var collectionView:UICollectionView?

    ///重用item的标识

   let itwmID = "shopID"

    ///商品数组

   lazy var shops:NSMutableArray? = {

        

        returnNSMutableArray()

        

    }()

    

   override func viewDidLoad() {

       super.viewDidLoad()

        

       //初始化布局

       self.setupLayout()

        //初始化上拉加载更多,下拉加载

        self.setupRefresh()

        self.loadNewShops()

    }

    

    //MARK:初始化数据

   private func setupList(){

        

       for i in 0...10{

            

           var model:NSDictionary?

            

           if Int(i % 2) == 0{

                

                model = ["w":NSNumber(int:200),"h":NSNumber(int:300),"img":"http://s6.mogujie.cn/b7/bao/131008/q2o17_kqyvcz3ckfbewv3wgfjeg5sckzsew_330x445.jpg_200x999.jpg","price":""]

                

            }else{

                

                model = ["w":NSNumber(int:200),"h":NSNumber(int:400),"img":"http://s6.mogujie.cn/b7/bao/131008/q2o17_kqyvcz3ckfbewv3wgfjeg5sckzsew_330x445.jpg_200x999.jpg","price":""]

            }

            

           self.shops?.addObject(model!)

        }

        self.collectionView?.header.endRefreshing()

        self.collectionView?.footer.endRefreshing()

    }

    

    //MARK:初始化的内容

   private func setupRefresh(){

        

        self.collectionView?.addLegendHeaderWithRefreshingTarget(self, refreshingAction: "loadNewShops")//header = MJRefreshNormalHeader(refreshingTarget: self, refreshingAction: "loadNewShops")

        self.collectionView?.addLegendFooterWithRefreshingTarget(self, refreshingAction: "loadMoreShops")//footer = MJRefreshAutoFooter(refreshingTarget: self, refreshingAction: "loadMoreShops")

        self.collectionView?.footer.hidden =true

    }

    

   private func setupLayout(){

        

       let layout = OOWaterflowLayout()

        layout.delegate =self

        //创建collectionView

       let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)

        collectionView.backgroundColor =UIColor.whiteColor()

        collectionView.dataSource =self

       self.view.addSubview(collectionView)

        collectionView.registerNib(UINib(nibName:"OOShopCell", bundle: nil), forCellWithReuseIdentifier: itwmID)

       self.collectionView = collectionView

        

    }

    

    

    ///加载新数据

   func loadNewShops(){

        

        self.shops?.removeAllObjects()

       self.setupList()

       //刷新数据

        self.collectionView?.reloadData()

        self.collectionView?.header.endRefreshing()

    }

    

    ///加载更多的数据

   func loadMoreShops(){

        

       self.setupList()

       //刷新数据

        self.collectionView?.reloadData()

        self.collectionView?.footer.endRefreshing()

        

    }

    

   override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        

    }

    

}



extension ViewController:UICollectionViewDataSource{

    

    //MARK:UICollectionViewDataSource的数据源

   func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        

        self.collectionView?.footer.hidden = (self.shops?.count == 0)

       return (self.shops?.count)!

    }

    

   func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        

       let cell = collectionView.dequeueReusableCellWithReuseIdentifier(itwmID, forIndexPath: indexPath)as? OOShopCell

        cell?.shops =self.shops![indexPath.item]as? NSDictionary

       return cell!

    }

    

}


extension ViewController:OOWaterflowLayoutDeledate{

    

    ///必须实现的方法

   func waterflowLayout(waterflowLayout waterflowLayout:OOWaterflowLayout, heightForItemAtIndex index:NSInteger, itemWidth width: CGFloat) -> CGFloat {

        

       let shop = self.shops![index]as! NSDictionary

       return width * CGFloat(shop["h"]as! NSNumber) /CGFloat(shop["w"as! NSNumber)

    }

    

    //MARK:下边的代理可以不实现有默认值

    ///返回列数

   func columnCountInWaterflowLayout(waterflowLayout:OOWaterflowLayout) -> NSInteger {

        

       return 2

    }

    

    ///返回列间距

   func columnMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) -> CGFloat {

        

       return 10

    }

    

    ///返回行间距

   func rowMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) -> CGFloat {

        

       return 10

    }

    

    ///返回内边距

   func edgeInsetsInWaterflowLayout(waterflowLayout:OOWaterflowLayout) -> UIEdgeInsets {

        

       return UIEdgeInsetsMake(20,10, 10, 10)

    }

}






//  OOWaterflowLayout.swift

//  swift瀑布流


import UIKit


class OOWaterflowLayout:UICollectionViewLayout {


    ///代理

    weakvar delegate:OOWaterflowLayoutDeledate?

    ///默认的列数

   let OODefaultColumnCount:NSInteger =2

    /** 每一列之间的间距 */

   let OODefaultColumnMargin:CGFloat =10

    /** 每一行之间的间距 */

   let OODefaultRowMargin:CGFloat =10

    /** 边缘间距 */

   let OODefaultEdgeInsets:UIEdgeInsets =UIEdgeInsetsMake(10,10, 10, 10)

    

    /** 存放所有cell的布局属性 */

    lazyvar attrsArray:[UICollectionViewLayoutAttributes] = {return [UICollectionViewLayoutAttributes]()}()

    /** 存放所有列的当前高度 */

   lazy var columnHeights:NSMutableArray = {returnNSMutableArray()}()

   var contentHeight:CGFloat?

    

    ///行间距

   var rowMargin:CGFloat{

        

       get{

            

            if ((self.delegate?.respondsToSelector("rowMarginInWaterflowLayout:")) == true){

            

               return (self.delegate?.rowMarginInWaterflowLayout!(self))!

            }else{

            

                returnOODefaultRowMargin

            }

            

        }

        

    }

    

    ///列间距

   var columnMargin:CGFloat{

        

       get{

            

            if ((self.delegate?.respondsToSelector("columnMarginInWaterflowLayout:")) == true){

                

               return (self.delegate?.columnMarginInWaterflowLayout!(self))!

            }else{

                

                returnOODefaultColumnMargin

            }

            

        }

    }

    

    ///列数

   var columnCount:NSInteger{

        

       get{

            

            if ((self.delegate?.respondsToSelector("columnMarginInWaterflowLayout:")) == true){

                

               return (self.delegate?.columnCountInWaterflowLayout!(self))!

            }else{

                

                returnOODefaultColumnCount

            }

            

        }

    }

    

    ///边距

   var edgeInsets:UIEdgeInsets{

        

       get{

            

            if ((self.delegate?.respondsToSelector("edgeInsetsInWaterflowLayout:")) == true){

                

               return (self.delegate?.edgeInsetsInWaterflowLayout!(self))!

            }else{

                

                returnOODefaultEdgeInsets

            }

            

        }

    }


}



//MARK:初始化和计算

extension OOWaterflowLayout{


    ///1.布局的初始化操作

   override func prepareLayout() {

        super.prepareLayout()

        

        self.contentHeight =0

        //清除之前计算的高度

        self.columnHeights.removeAllObjects()

       for _ in 0...self.columnCount -1{

        

            self.columnHeights.addObject(self.edgeInsets.top)

        }

        

        //清除之前所有的布局属性

        self.attrsArray.removeAll()

        

        //创建每一个cell的布局属性

        let count =self.collectionView?.numberOfItemsInSection(0)

       for var i =0;i < count;i++ {

        

           let indexpath = NSIndexPath(forItem: i, inSection:0)

           //获取布局属性

            let attrs =self.layoutAttributesForItemAtIndexPath(indexpath)

           self.attrsArray.append(attrs!)

        }

        

    }


    ///2.决定cell的排布

   override func layoutAttributesForElementsInRect(rect:CGRect) -> [UICollectionViewLayoutAttributes]? {

        

       return self.attrsArray

    }

    

    ///3.返回indexPath位置cell对应的布局属性

   override func layoutAttributesForItemAtIndexPath(indexPath:NSIndexPath) -> UICollectionViewLayoutAttributes? {

        

        //创建布局属性

       let attrs = UICollectionViewLayoutAttributes(forCellWithIndexPath:indexPath)

        //创建collectionView的宽度

       let collectionViewW = self.collectionView?.frame.size.width

       let coCount:CGFloat =CGFloat(NSNumber(integer:self.columnCount))

        //设置布局的frame

       let w:CGFloat = (collectionViewW! -self.edgeInsets.left -self.edgeInsets.right - (coCount -1) * self.columnMargin) / coCount

       let h:CGFloat = (self.delegate?.waterflowLayout(waterflowLayout:self, heightForItemAtIndex: indexPath.item, itemWidth: w))!

        

        //找出高度最短的那一列

       var destColumn:CGFloat =0

       var minColumnHeight:CGFloat = (self.columnHeights[0]as? CGFloat)!

       for var i =1;i < self.columnCount;i++ {

            

           let columnHeight = (self.columnHeights[i]as? CGFloat)!

           if minColumnHeight > columnHeight{

            

                minColumnHeight = columnHeight

                destColumn =CGFloat(i)

            }

        }

        

       let x:CGFloat =self.edgeInsets.left + destColumn * (w +self.columnMargin)

       var y:CGFloat = minColumnHeight

       if y != self.edgeInsets.top{

        

            y +=self.rowMargin

        }

        

        attrs.frame =CGRectMake(x, y, w, h)

        

        //更新最短的那一列的高度

       self.columnHeights[NSInteger(destColumn)] =CGRectGetMaxY(attrs.frame)

        

        //记录内容的高度

       let columnHeight:CGFloat =self.columnHeights[NSInteger(destColumn)]as! CGFloat

        

       if self.contentHeight < columnHeight{

        

           self.contentHeight = columnHeight

        }

        

       return attrs

    }

    

    

   override func collectionViewContentSize() ->CGSize {


        returnCGSizeMake(0,self.contentHeight! +self.edgeInsets.bottom)


    }

    

}


//MARK:代理

@objcprotocol OOWaterflowLayoutDeledate:NSObjectProtocol{


    ///返回每个item的高度必须实现

   func waterflowLayout(waterflowLayout waterflowLayout:OOWaterflowLayout,heightForItemAtIndex index:NSInteger,itemWidth width:CGFloat)->CGFloat

    ///返回的列数不实现默认为3

   optional func columnCountInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->NSInteger

    ///返回列间距,默认为10

   optional func columnMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->CGFloat

    ///返回行间距,默认为10

   optional func rowMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->CGFloat

    ///返回内边距,默认为(10,10,10,10)

   optional func edgeInsetsInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->UIEdgeInsets

    

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值