Search code examples
swiftuicollectionviewuicollectionviewcellcgrect

custom cell and custom height for each


I output 4 custom cells via the switch function now I need to output either a dynamic height value or a fixed height value for each of them. I like both, as their height is always static.

I subscribed to The uiСollectionviewВelegateFlowLayout Protocol and found how to change the height of all cells

func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        let size = CGSize(width: 357, height: 600)
        return size

to override the height of individual cells I use the function

cell.frame = CGRect(cell.frame.origin.x, cell.frame.origin.y, width: 100.0, height: 100.0)

but it doesn't work, "Expression type '@lvalue CGRect' is ambiguous without more context"

what should I do in this case? what function to use?

full code below

// main protocols UICollectionView
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    // width and height for cell in collectionView
    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        let size = CGSize(width: 357, height: 600)
        return size
    }


    //margins for cell in collectionView
    func collectionView(_ collectionView: UICollectionView, layout
        collectionViewLayout: UICollectionViewLayout,
                        minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 40.0
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 4
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


            var cell: UICollectionViewCell!

            switch indexPath.row {
            case 1:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "secondCell", for: indexPath)
                    as? secondCollectionViewCell
                cell.frame = CGRect(cell.frame.origin.x, cell.frame.origin.y, width: 100.0, height: 100.0)

            case 2:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "thirdCell", for: indexPath)
                    as? cellThirdCollectionViewCell

            case 3:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "fourthCell", for: indexPath)
                    as? fourthCollectionViewCell

            default:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath)
                    as? imageModelCollectionViewCell
            }
            return cell
        }
    }

enter image description here


Solution

  • extension ViewController : UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            switch indexPath.row {
            case 1:
                return CGSize(width: 100, height: 200)
            case 2:
                return CGSize(width: 100, height: 300)
            case 3:
                return CGSize(width: 100, height: 400)
            default:
                return CGSize(width: 100, height: 100)
            }
        }
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    
            var cell: UICollectionViewCell!
    
            switch indexPath.row {
            case 1:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "firstCell", for: indexPath)
                    as? firstCollectionViewCell
    
    
            case 2:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "secondCell", for: indexPath)
                    as? secondCollectionViewCell
    
            case 3:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "thirdCell", for: indexPath)
                    as? thirdCollectionViewCell
    
            default:
                cell = collectionView.dequeueReusableCell(withReuseIdentifier: "imageCell", for: indexPath)
                    as? imageModelCollectionViewCell
            }
            return cell
        }
    }
    

    completely solves the problem don't forget add

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.delegate = self
    }
    

    p.s. If You get an error with "collectionView.delegate = self" is a possible reason that you are working in a viewController and not in a collectionViewController

    You need to add IBOutlet