横向排版的CollectionView

作者: sun5kong | 来源:发表于2017-07-24 17:28 被阅读440次

    需求: 固定高度的区域, 里面左右分页显示多个图标, 每页从左往右排列, 排满后从上往下排, 这一页排满后排下一页.参照oc的实现方式

    如图所示

    我们很容易想到利用UICollectionView来实现, 设置UICollectionViewFlowLayout, 然后设置为横向.代码如下:

    fileprivate lazy var collectionView: UICollectionView = { [unowned self] in
            let layout = UICollectionViewFlowLayout()
            layout.minimumLineSpacing = 0
            layout.minimumInteritemSpacing = 0
    //        layout.rowCount = 2
    //        layout.itemCountPerRow = 3
            layout.itemSize = CGSize(width: self.zs_width / 3.0, height: self.zs_width / 3.0 + 60.0)
            layout.scrollDirection = .horizontal
            
            let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
            collectionView.frame = CGRect(x: 0, y: 0, width: self.zs_width, height: self.zs_height - 20.0)
            collectionView.showsVerticalScrollIndicator = false
            collectionView.showsHorizontalScrollIndicator = false
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "CELLID")
            collectionView.isPagingEnabled = true
            return collectionView
        }()
    

    这段代码实现的效果:


    p2

    怎么实现上述效果呢?

    1. 可以用大cell包含5个小图标来实现(这样就比较复杂)
    2. 重写UICollectionViewFlowLayout

    这里我用重写UICollectionViewFlowLayout实现

    思路: 获取collectionView所有cell的属性, 然后进行indexpath的计算, 用新计算出的indexPath替换原有的indexPath.

    1.声明属性
        /** 一行中cell的个数*/
        public var itemCountPerRow: Int!
        /** 一页显示多少行*/
        public var rowCount: Int!
        /** 存储collectionView上cell的属性*/
        fileprivate var allAttributes: [UICollectionViewLayoutAttributes] = []
    
    2.获取所有cell的属性
        override func prepare() {
            super.prepare()
            let count = self.collectionView?.numberOfItems(inSection: 0) ?? 0
            for i in 0..<count {
                let indexPath = NSIndexPath(item: i, section: 0)
                let attributes = self.layoutAttributesForItem(at: indexPath as IndexPath)
                allAttributes.append(attributes!)
            }
        }
    

    3.交换indexPath

        override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
            var item = indexPath.item
            
            var x = 0
            var y = 0
            self.targetPosition(item: item, x: &x, y: &y)
            item = originItem(x, y: y)
            let newIndexPath = NSIndexPath(item: item, section: 0)
            let theNewAttr = super.layoutAttributesForItem(at: newIndexPath as IndexPath)
            theNewAttr?.indexPath = indexPath
            return theNewAttr
        }
        
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            let attributes = super.layoutAttributesForElements(in: rect)
            var tmp: [UICollectionViewLayoutAttributes] = []
            for attr in attributes! {
                for attr2 in self.allAttributes {
                    if attr.indexPath.item == attr2.indexPath.item {
                        tmp.append(attr2)
                        break
                    }
                }
            }
            return tmp
        }
        //根据item计算出目标item的偏移量
        //x 横向偏移 y 竖向偏移
        fileprivate func targetPosition(item: Int, x: inout Int, y: inout Int) {
            let page = item / (self.itemCountPerRow * self.rowCount)
            
            x = item % self.itemCountPerRow + page * self.itemCountPerRow
            y = item / self.itemCountPerRow - page * self.rowCount
            
        }
        //根据偏移量计算item
        fileprivate func originItem(_ x: Int, y: Int) -> Int {
            let item = x * self.rowCount + y
            return item
        }
    

    相关文章

      网友评论

        本文标题:横向排版的CollectionView

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