swift瀑布流自定义布局实现

来源:互联网 发布:钱龙软件使用说明 编辑:程序博客网 时间:2024/06/09 11:56

demo github下载地址

https://github.com/liwei5bao/SwiftWaterfallProject

//  ViewController.swift

//  SwiftWaterfall

import UIKit


import UIKit


class ViewController:UIViewController{

    

   var collectionView:UICollectionView?

    ///重用item的标识

   let itwmID ="shopID"

    ///商品数组

   lazyvar shops:NSMutableArray? = {

        

        returnNSMutableArray()

        

    }()

    

   overridefunc viewDidLoad() {

       super.viewDidLoad()

        

       //初始化布局

       self.setupLayout()

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

        self.setupRefresh()

        self.loadNewShops()

    }

    

    //MARK:初始化数据

   privatefunc setupList(){

        

       for iin 0...10{

            

           var model:NSDictionary?

            

           ifInt(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:初始化的内容

   privatefunc 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

    }

    

   privatefunc 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()

        

    }

    

   overridefunc 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 {

        

       return2

    }

    

    ///返回列间距

   func columnMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->CGFloat {

        

       return10

    }

    

    ///返回行间距

   func rowMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->CGFloat {

        

       return10

    }

    

    ///返回内边距

   func edgeInsetsInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->UIEdgeInsets {

        

       returnUIEdgeInsetsMake(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]()}()

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

   lazyvar 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.布局的初始化操作

   overridefunc 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)

       forvar i =0;i < count;i++ {

        

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

           //获取布局属性

            let attrs =self.layoutAttributesForItemAtIndexPath(indexpath)

           self.attrsArray.append(attrs!)

        }

        

    }


    ///2.决定cell的排布

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

        

       returnself.attrsArray

    }

    

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

   overridefunc 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)!

       forvar 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

        

       ifself.contentHeight < columnHeight{

        

           self.contentHeight = columnHeight

        }

        

       return attrs

    }

    

    

   overridefunc 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

   optionalfunc columnCountInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->NSInteger

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

   optionalfunc columnMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->CGFloat

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

   optionalfunc rowMarginInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->CGFloat

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

   optionalfunc edgeInsetsInWaterflowLayout(waterflowLayout:OOWaterflowLayout) ->UIEdgeInsets

    

}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 鞋不透气脚臭怎么办 卫生间窗在厨房怎么办 联想保修期过了怎么办 s8背面碎了怎么办 三星c5玩游戏卡怎么办 三星关机键失灵怎么办 购机凭证丢了怎么办 滴滴没人接单怎么办 头发干怎么办才好 唯品会东西碎了怎么办 唯品会买东西有质量问题怎么办 来分期不能退货怎么办 商场不肯退衣服怎么办 唯品会衣服坏了怎么办 京东买电视拆机坏的怎么办 余额宝资金冻结怎么办? 余额宝金额冻结怎么办 adidas买了假货怎么办 余额宝冻结金额怎么办 买到不合格地板怎么办 买到翻新地板怎么办 食品里有头发怎么办 家具环保不达标怎么办 买到坏了的食物怎么办 空调检测不合格的怎么办 淘宝卖精仿遇到打假怎么办? 没有收到提货码怎么办 增值税发票超过180天怎么办 花呗借钱还不上怎么办 实体店里没人气怎么办 EMS快件无人签收怎么办 邮政快递丢失了怎么办 快递手机丢了怎么办 拍照签收没收到怎么办 拼多多开店货源怎么办 被购买鉴定投诉怎么办 淘宝上买东西错想用花呗怎么办 淘宝想用花呗买东西差一点怎么办 买了假货怎么办还用吗 免税店买完东西怎么办 淘宝恶意拍单怎么办