Sections with different cell sizes with UICollectionView

I need to create a view in a Swift project with two differentiation sections. The first has seven square-shaped cells. The second has three cells with a rectangular shape. The data inside the cells is static. In all cases, sections should correspond to the entire width of the screen (mainly in landscape mode).

I do not have much experience using it UICollectionViewController, so I decided to accomplish this using one class UICollectionViewControllerand two reusable cells, but when I set the cell width of the first section, the second one also affects, and then the cell width is cut.

Is my point of view correct? Should I use different ones UICollectionViewController(one for each 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
    }
}

Builder Interface Configuration for CollectionView enter image description here

Screenshot Simulator (not the desired result, all cells have the same width) enter image description here

+4
source share
2 answers

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

In your case, you can 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 in your collectionViewController class.
Set heightto what should be at the height of your cell. You can customize widthif you use spacing between cells or inserts in your collection.

+5
source

for Swift 4

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let width : CGFloat
    let height : CGFloat

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

func collectionView(_ collectionView: UICollectionView,
                layout collectionViewLayout: UICollectionViewLayout,
                minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 1.0
}

func collectionView(_ collectionView: UICollectionView, layout
    collectionViewLayout: UICollectionViewLayout,
                    minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 1.0
}
0
source

Source: https://habr.com/ru/post/1652242/


All Articles