Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sections with different cell size with UICollectionView

I have to create a view in a Swift project with two differentiate sections. The first one has seven cells with square shape. The second one has three cells with rectangular shape. Data inside cells are static. In all cases, the sections should fit the entire screen width (mostly in landscape mode).

I don't have much experience using UICollectionViewController so I decided to accomplish this using one UICollectionViewController class and two reusable cells, but when I set the first section cell width the second one is also affected and then cells width is cut.

Is my point correct? Shall I use different UICollectionViewControllers (one per section)?

Update: My Controller code

import UIKit

class InverterController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    let moduleCell = "moduleCell"
    let parameterCell = "parameterCell"

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        if section > 0 {
            return CGSizeZero
        } else {
            return CGSize(width: collectionView.frame.width, height: CGFloat(195))
        }
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtPath indexPath: NSIndexPath) -> CGSize {

        var newSize = CGSizeZero

        if indexPath.section == 0 {

            newSize =  CGSizeMake(CGFloat(105), CGFloat(105))
        } else {
            newSize = CGSizeMake(CGFloat(313), CGFloat(200))
        }

        return newSize
    }

    override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
        switch kind {
            case UICollectionElementKindSectionHeader:
                let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "inverterHeader", forIndexPath: indexPath)
                return headerView
            default:
                assert(false, "Unexpected element kind")
        }
    }

    /**
     Two sections in this UICollectionView: First one for clock items, second one for other parameters.
     */
    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 2
    }

    /**
     First section contains one cell
     Second section contains three cells
     */
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        var items = 0

        if section == 0 {
            items = 7
        } else {
            items = 3
        }

        return items
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        var cellIdentifier = ""

        if indexPath.section == 0 {
            cellIdentifier = moduleCell
        } else {
            cellIdentifier = parameterCell
        }

        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(cellIdentifier, forIndexPath: indexPath)
        cell.layer.cornerRadius = 6
        cell.layer.masksToBounds = true

        return cell
    }
}

Interface Builder configuration for CollectionView enter image description here

Simulator screenshot (non desired result; all cells have the same width) enter image description here

like image 630
Spacemonkey Avatar asked Aug 23 '16 21:08

Spacemonkey


People also ask

How do you create a collection view with multiple sections?

You need to implement a custom UICollectionViewLayout. With a horizontal flow layout it's going to fill from top to bottom first, then move to the right. Since you have two rows, as specified in sizeForItemAt, section 0 will fill from top to bottom, then right to left, and so will section 1.

How do I change the size of a collectionView cell?

class MyLayout: UICollectionViewFlowLayout { override func prepare() { super. prepare() guard let collectionView = collectionView else { return } itemSize = CGSize(width: ..., height: ...) } }

Do collectionView use cells?

The collection view presents items onscreen using a cell, which is an instance of the UICollectionViewCell class that your data source configures and provides. In addition to its cells, a collection view can present data using other types of views.

How do I add a section title in UICollectionView?

There are no section headers in the UICollectionView. So for your first task, you'll add a new section header using the search text as the section title. To display this section header, you'll use UICollectionReusableView .


1 Answers

You can use collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize delegate method to adjust cell size.

In your case you could write something like this:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

    let width : CGFloat
    let height : CGFloat

    if indexPath.section == 0 {
        // First section
        width = collectionView.frame.width/7
        height = 50
        return CGSizeMake(width, height)
    } else {
        // Second section
        width = collectionView.frame.width/3
        height = 50
        return CGSizeMake(width, height)
    }

}

Put this code inside your collectionViewController class.
Set height to what your cell height should be. You might want to adjust width if you're using spacing between cells or insets in your collectionView.

like image 189
Sam_M Avatar answered Oct 04 '22 03:10

Sam_M