Home > Blockchain >  How do i know data is displayed in 3 horizontal rows in collectionView?
How do i know data is displayed in 3 horizontal rows in collectionView?

Time:09-29

I have array with 6 objects and I am displaying like below. What I need is I want to get horizontal row count as 3 How Can I get that with collection view..?

enter image description here

I am using below code to setting cell in center of the screen

class CollectionViewRow {

    var attributes = [UICollectionViewLayoutAttributes]()
    var spacing: CGFloat = 0

    init(spacing: CGFloat) {
        self.spacing = spacing
    }

    func add(attribute: UICollectionViewLayoutAttributes) {
        attributes.append(attribute)
    }

    var rowWidth: CGFloat {
        return attributes.reduce(0, { result, attribute -> CGFloat in
            return result   attribute.frame.width
        })   CGFloat(attributes.count - 1) * spacing
    }

    func centerLayout(collectionViewWidth: CGFloat) {
        let padding = (collectionViewWidth - rowWidth) / 2
        var offset = padding
        for attribute in attributes {
            attribute.frame.origin.x = offset
            offset  = attribute.frame.width   spacing
        }
    }
}

class UICollectionViewCenterLayout: UICollectionViewFlowLayout {

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let attributes = super.layoutAttributesForElements(in: rect) else {
            return nil
        }

        var rows = [CollectionViewRow]()
        var currentRowY: CGFloat = -1

        for attribute in attributes {
            if currentRowY != attribute.frame.midY {
                currentRowY = attribute.frame.midY
                rows.append(CollectionViewRow(spacing: 10))
            }
            rows.last?.add(attribute: attribute)
        }

        rows.forEach { $0.centerLayout(collectionViewWidth: collectionView?.frame.width ?? 0) }
        return rows.flatMap { $0.attributes }
    }
}

CodePudding user response:

If you're creating your own layout subclass then you can add a value to it like...

class UICollectionViewCenterLayout: UICollectionViewFlowLayout {

    var numberOfRows: Int = 0

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let attributes = super.layoutAttributesForElements(in: rect) else {
            return nil
        }

        var rows = [CollectionViewRow]()
        var currentRowY: CGFloat = -1

        for attribute in attributes {
            if currentRowY != attribute.frame.midY {
                currentRowY = attribute.frame.midY
                rows.append(CollectionViewRow(spacing: 10))
            }
            rows.last?.add(attribute: attribute)
        }

        rows.forEach { $0.centerLayout(collectionViewWidth: collectionView?.frame.width ?? 0) }

        // add this bit
        self.numberOfRows = rows.count

        return rows.flatMap { $0.attributes }
   }
}

Then in your view you can access the layout (or better still store it as a var) and get the numberOfRows from it.

if let layout = self.collectionView.collectionViewLayout as? namesLayout {
      print("numberOfRows===\(layout.numberOfRows)")
      rowsCount = layout.numberOfRows
  }

Also... don't call your own layout UICollectionView... just call it like CenterLayout or NamesLayout or something. :D Keeps it shorter.

  • Related