Tomasz Szulc
Tomasz Szulc

Reputation: 4235

Calculating height of UICollectionViewCell with text only

trying to calculate height of a cell with specified width and cannot make it right. Here is a snippet. There are two columns specified by the custom layout which knows the column width.

let cell = TextNoteCell2.loadFromNib()
var frame = cell.frame
frame.size.width = columnWidth // 187.5
frame.size.height = 0 // it does not work either without this line.
cell.frame = frame
cell.update(text: note.text)

cell.contentView.layoutIfNeeded()
let size = cell.contentView.systemLayoutSizeFitting(CGSize(width: columnWidth, height: 0)) // 251.5 x 52.5
print(cell) // 187.5 x 0
return size.height

Both size and cell.frame are incorrect.

Cell has a text label inside with 16px margins on each label edge.

Thank you in advance.

Upvotes: 0

Views: 1957

Answers (3)

Shahzaib Maqbool
Shahzaib Maqbool

Reputation: 1487

For Swift 4.2 updated answer is to handle height and width of uicollectionview Cell on the basis of uilabel text

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
  let size = (self.FILTERTitles[indexPath.row] as NSString).size(withAttributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14.0)])
    return CGSize(width: size.width + 38.0, height: size.height + 25.0)


}

Upvotes: 0

Kamran
Kamran

Reputation: 15248

To calculate the size for a UILabel to fully display the given text, i would add a helper as below,

extension UILabel {

   public static func estimatedSize(_ text: String, targetSize: CGSize = .zero) -> CGSize {
       let label = UILabel(frame: .zero)
       label.numberOfLines = 0
       label.text = text
       return label.sizeThatFits(targetSize)
   }
}

Now that you know how much size is required for your text, you can calculate the cell size by adding the margins you specified in the cell i.e 16.0 on each side so, the calculation should be as below,

let intrinsicMargin: CGFloat = 16.0 + 16.0
let targetWidth: CGFloat = 187.0 - intrinsicMargin
let labelSize = UILabel.estimatedSize(note.text, targetSize: CGSize(width: targetWidth, height: 0))
let cellSize = CGSize(width: labelSize.width + intrinsicMargin, height: labelSize.height + intrinsicMargin)

Hope you will get the required results. One more improvement would be to calculate the width based on the screen size and number of columns instead of hard coded 187.0

Upvotes: 1

Lefteris
Lefteris

Reputation: 14677

That cell you are loading from a nib has no view to be placed in, so it has an incorrect frame.

You need to either manually add it to a view, then measure it, or you'll need to dequeu it from the collectionView so it's already within a container view

Upvotes: 1

Related Questions