UICollectionView "flow direction"

1.4k Views Asked by At

the typical flow for the UICollectionView is to "move across, then down"

enter image description here

I was curious if there was a way to reverse the order of the "flow" i.e go "down first" (for maximum rows, then across.) Similar to this:

enter image description here

2

There are 2 best solutions below

3
On

Thanks @Caleb for inspiring me. I tried the following setup

class ViewController: UIViewController {
    let items = ["A", "B", "C", "D", "E"]

    // other unnecessary stuff for this demonstration
}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if section == 0 {
            return ((items.count + 1) / 2) // just ceiling, after dividing by 2
        } else  if section == 1 {
            return items.count - ((items.count + 1) / 2) // calculating the remainder item
        } else {
            return 0
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)

        var text = "";
        if indexPath.section == 0 {
            // take the even part
            text = items[indexPath.row * 2]
        } else {
            // take the odd part
            text = items[(indexPath.row * 2) + 1]
        }

        (cell.subviews[0].subviews[0] as? UILabel)?.text = text

        return cell
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }
}

I set the scroll direction to vertical and the output looks like. It will work both for odd number of item and even number of item.

Output

Clearly this isn't the OP is looking for. Here i've used two different sections, but OP want to make the zig-zag pattern within a section. That certainly not possible as @Caleb sorted out, without filling width wise we cannot go down in vertical direction.

5
On

I was curious if there was a way to reverse the order of the "flow" i.e go "down first" (for maximum rows, then across.)

There's no way to get UICollectionFlowLayout to layout the cells in column-major order — it "flows" the cells across first, and then down. That makes sense if you think about it -- how would UICollectionFlowLayout know how many cells to place in the first column before starting the second? As it is, it just places as many as will fit in the row before moving to the next row. But since you want the scrolling direction to remain vertical, it wouldn't have any reason to stop adding cells to the first column.

But UICollectionView will happily put the cells wherever you like -- you just have to create your own custom layout object to tell it where to put them. That doesn't have to be as daunting as it might sound... laying out cells on a grid isn't rocket science, and your collection layout object doesn't have to be as robust as UICollectionFlowLayout is -- it only has to meet your specific needs.