Eri-Sklii
Eri-Sklii

Reputation: 589

Change UICollectionView cell size depending on label size

How can I change the UICollectionView cell height? enter image description here

As you can see, the text just stops with "...". I want the size to get bigger when the label I bigger, I want the cell size to go below the label. How can I do this? Hope you understand my question.. Anyone please?

Upvotes: 0

Views: 5116

Answers (3)

Erik Auranaune
Erik Auranaune

Reputation: 1414

This answer does not change the cell size at all, but it could be a solution to your problem. In your cellForItemAtIndexPath after you set your cell: let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CollectionViewCell

Try adding this: cell.imageText.adjustsFontSizeToFitWidth = true

This will make the font fit the label size, and the more text the smaller font size. Let me know how this worked for you.

Upvotes: 2

Kumuluzz
Kumuluzz

Reputation: 2012

You should make use of a delegate method called collectionView:layout:sizeForItemAtIndexPath from the UICollectionViewDelegateFlowLayout.


Now, the actual implementation will depend on your specific case (is it local content, if it is downloaded over the network, how many custom cells you have, etc.), but here's a copy of a very simple UICollectionViewController which works.

It makes use of a single custom cell of the type MyAwesomeCell which has a single label outlet called myAwesomeLabel.

I have not made any changes in the storyboard concerning Preferred Width, Content Compression Resistance Priority, etc. The only important change I have made is setting the lines property to 0 for the label, which means unlimited amount of lines.

PS, it's been written in Swift 2.


//
//  ViewController.swift
//  CollectionCell
//
//  Created by Stefan Veis Pennerup on 21/09/15.
//  Copyright © 2015 Kumuluzz. All rights reserved.
//

import UIKit

class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    // MARK: - Constants

    struct Constants {
        static let ReuseIdentifierMyAwesomeCell = "myAwesomeCell"
    }

    // MARK: - Models

    let myAwesomeCells = [
        "Lorem ipsum dolor sit amet.",
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed massa leo, mollis id tortor at posuere.",
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque semper vitae mi vel hendrerit. Suspendisse et feugiat mi. Donec quis sollicitudin quam, non porttitor nulla. Phasellus in luctus lorem, sed auctor enim. Suspendisse potenti. Ut maximus pharetra diam, ac laoreet est dignissim eu nullam."
    ]

    var cellSizes: [CGSize]!

    // MARK: - Lifecycle methods

    override func viewDidLoad() {
        super.viewDidLoad()

        // Gives the size array an initial value since collectionView:layout:sizeForItemAtIndexPath
        // is called before collectionView:cellForItemAtIndexPath
        cellSizes = myAwesomeCells.map({ _ in return CGSize(width: 200, height: 50) })
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        // Now that the collection view has appeared, then all the cells have been initialized
        // with their appropiate content. The view should then be reloaded with the newly
        // calculated sizes as well.
        collectionView?.reloadData()
    }

    // MARK: - UICollectionViewDataSource

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        NSLog("\(self), collectionView:numberOfItemsInSection")
        return myAwesomeCells.count
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        NSLog("\(self), collectionView:cellForItemAtIndexPath")

        // Configures the cell
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Constants.ReuseIdentifierMyAwesomeCell, forIndexPath: indexPath) as! MyAwesomeCell
        cell.myAwesomeLabel.text = myAwesomeCells[indexPath.item]

        // Calculates the height
        cell.setNeedsLayout()
        cell.layoutIfNeeded()
        cellSizes[indexPath.item] = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

        // Returns the new cell
        return cell
    }

    // MARK: - UICollectionViewDelegate

    // MARK: - UICollectionViewDelegateFlowLayout

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        NSLog("\(self), collectionView:layout:sizeForItemAtIndexPath")
        return cellSizes[indexPath.item]
    }

}

Upvotes: 1

Niko Zarzani
Niko Zarzani

Reputation: 1402

Try creating a fake Label with the same text, call sizetofit on it and then see the actual size of the label with full text.

Then, once you get the heigth, you can set it into your collectionViewLayout itemSize property.

I believe this way all your collectionview cell will be bigger but maybe it can be a starting point for a better solution...

Upvotes: 0

Related Questions