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

2016-09-05  本文已影响75人  mkb2

知识点:
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
    }

上一篇下一篇

猜你喜欢

热点阅读