LofiMAM
LofiMAM

Reputation: 127

CollectionView sections

I have a collectionview and I want it to be of n section where each section has a ten of cells, my problem is: Maybe n equals thirty five, in this case I want to show 3 section with ten of cells and the last section with just five.

Upvotes: 3

Views: 934

Answers (3)

arun siva
arun siva

Reputation: 869

You can split the array into chunks using this extension

extension Array {
    func chunked(into size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[$0 ..< Swift.min($0 + size, count)])
        }
    }
}

If count is 35 -> [10,10,10,5]

If count is 30 -> [10,10,10]

If count is 29 -> [10,10,9]

Then use the two dimensional array in collectionview delegate methods

class ViewController: UIViewController, UICollectionViewDataSource {
    let array = Array(1...35)
    lazy var chunkedArray = array.chunked(into: 10)

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return chunkedArray.count
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return chunkedArray[section].count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        print(chunkedArray[indexPath.section][indexPath.item])
        return cell
    }
}

enter image description here

Upvotes: 1

RajeshKumar R
RajeshKumar R

Reputation: 15758

If array count is 35 return count/10 if count%10 is 0 else return count/10+1 in numberOfSections method

In numberOfItemsInSection method multiply current section with 10 and subtract from count. return min value of 10 or subtracted value

In cellForItemAt method multiply section with 10 and add row to get the array index

class ViewController: UIViewController, UICollectionViewDataSource {
    var arr = Array(1...35)
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return (arr.count/10) + (arr.count%10 == 0 ? 0 : 1)
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return min(10,arr.count - (10*section))
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? Cell
        let currentStr = arr[(indexPath.section*10)+indexPath.item]
        cell?.label.text = "\(currentStr)"
        return cell!
    }
}

enter image description here

Upvotes: 2

PGDev
PGDev

Reputation: 24341

You can simply implement UICollectionViewDataSource methods and configure collectionView(_:numberOfItemsInSection:) method based on the each section for number of cells.

let n = 35 //It specify the total elements count

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return n/10
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    switch section {
    case (n/10):
        return (n % 10)

    default:
        return 10
    }
}

In the above code, the collectionView will have

  • (n % 10) cells for last section
  • 10 cells for other sections

Kindly clarify your conditions so I can update the code accordingly.

Upvotes: 1

Related Questions