美文网首页
其他两种layout布局-1.写出这样的布局

其他两种layout布局-1.写出这样的布局

作者: mkb2 | 来源:发表于2016-09-05 08:52 被阅读75次

    知识点:
    1.如果要删除tableview,或者colletionView的某个cell,步骤分两个 第一,删除数据源中的,第二是删除collection的中,然后刷新,顺序必须这样,如果顺序颠倒,那么数据源中获取的index是不对的!
    2.现在想创建一个可变数组,并且数组中只能放置某种类型的对象,如何写?private lazy var attrisArr = [UICollectionViewLayoutAttributes]()
    使用的时候用调用attrisArr.append(attri)这个方法,addObject不能用了,感觉怪怪的

    这个问题就是说数组越界,就是我在count改不成count!,否则系统认为可能是0,所以越界

    本文要写一个这样的效果

    继承UICollectionViewLayout奥

    思路
    1.自定义一个layout
    2.重写layoutAttributesForElementsInRect方法
    3.手动计算不同cell所在的attri.frame
    4.计算content size
    5.代码重构

    1.自定义一个layout

    自定义一个SFGridLayout手动开始写布局,因为父类是UICollectionViewLayout所以所有的布局都要自己写

    2.重写layoutAttributesForElementsInRect方法

    过去都要调用super. layoutAttributesForElementsInRect方法获取到每个cell的attributeLayout,现在不用了,因为我们之前继承的是流水布局,他会给我们算好位置等等属性,但是我们现在继承的是一个抽象的类,所以啥也没有,只能靠自己来计算,所以我们自己创建和返回一个数组。

    2.1懒加载一个数组,里面放置的是UICollectionViewLayoutAttributes对象
    //懒加载数据
        private lazy var attrisArr = [UICollectionViewLayoutAttributes]()
    //实际调用
        attrisArr.append(attri)
    
    3.手动计算不同cell所在的attri.frame
    结构剖析图

    分析之后,看到的前六个是有规律的,那么先给前六个布局试试

    let indexPath = NSIndexPath.init(forItem: index, inSection: 0)
                let attri = UICollectionViewLayoutAttributes.init(forCellWithIndexPath: indexPath)
                let width = UIScreen.mainScreen().bounds.width * 0.5
                var height:CGFloat = 0
                var x:CGFloat = 0
                var y:CGFloat = 0
                if(index == 0){
                    height = width
                    x = 0
                    y = 0
                }else if(index == 1){
                    height = width*0.5
                    x = width
                    y = 0
                }else if(index == 2){
                    height = width*0.5
                    x = width
                    y = height
                }else if(index == 3){
                    height = width*0.5
                    x = 0
                    y = width
                }else if(index == 4){
                    height = width*0.5
                    x = 0
                    y = height+width
                }else if(index == 5){
                    height = width
                    x = width
                    y = width
                }
    
    前六个照片

    六个以后,就是获取attrisArr[index - 6] 和对象,其他的属性都是一致的,唯独是y应该是加上width*2,请自行补脑

    //接上段代码
    else{
                    let lastAttr = attrisArr[index-6]
                    x = lastAttr.frame.origin.x
                    y = 2*width + lastAttr.frame.origin.y;
                    height = lastAttr.frame.height
                }
                
                attri.frame = CGRectMake(x, y, width, height)
                attrisArr.append(atria)
    
    

    4.计算content size
    这样就可以做出这样的效果

    布局完事了

    但还是有一定的问题,就是不能滑动,为啥,因为你自定义了抽象类的布局,所有的东西都要自己去出去好吗!
    所以啊,我们应该重写一个方法,返回collectionViewcontensize属性

        //重写contensize方法
        override func collectionViewContentSize() -> CGSize {
            //获取最后一个
    //        let arr = layoutAttributesForElementsInRect(CGRectZero)
            let count = collectionView?.numberOfItemsInSection(0)
            let rows = (count!+3-1)/3
            let rowH = (collectionView?.frame.size.width)! * 0.5
            return CGSizeMake(0, rowH * CGFloat(rows))
        }
    

    5.代码重构
    刚才说到在layoutAttributesForElementsInRect计算cell组的东西,多少有些麻烦,影响效率,因为每次rect变化,都要调用这个方法,重新计算一下,所以不好,应该是只计算一次,所以放到prepareLayout方法中,

    override func prepareLayout() {
            super.prepareLayout()
            //假设只有一组
            let count = collectionView?.numberOfItemsInSection(0)
            
            for index in 0 ..< count!
            {
                
                let indexPath = NSIndexPath.init(forItem: index, inSection: 0)
                let attri = UICollectionViewLayoutAttributes.init(forCellWithIndexPath: indexPath)
                let width = UIScreen.mainScreen().bounds.width * 0.5
                var height:CGFloat = 0
                var x:CGFloat = 0
                var y:CGFloat = 0
                if(index == 0){
                    height = width
                    x = 0
                    y = 0
                }else if(index == 1){
                    height = width*0.5
                    x = width
                    y = 0
                }else if(index == 2){
                    height = width*0.5
                    x = width
                    y = height
                }else if(index == 3){
                    height = width*0.5
                    x = 0
                    y = width
                }else if(index == 4){
                    height = width*0.5
                    x = 0
                    y = height+width
                }else if(index == 5){
                    height = width
                    x = width
                    y = width
                }else{
                    let lastAttr = attrisArr[index-6]
                    x = lastAttr.frame.origin.x
                    y = 2*width + lastAttr.frame.origin.y;
                    height = lastAttr.frame.height
                }
                
                attri.frame = CGRectMake(x, y, width, height)
                attrisArr.append(attri)
            }
    
        }
        
        /**
         *  重写返回布局属性数组
         */
        override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]?
        {
            return attrisArr
        }
    
    

    相关文章

      网友评论

          本文标题:其他两种layout布局-1.写出这样的布局

          本文链接:https://www.haomeiwen.com/subject/ylzlettx.html