iOS - How to dynamically update UICollectionViewCell size after label text changed

2.8k Views Asked by At

So I have a cell in UICollectionView

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        var cell: myCell = collectionView.dequeueReusableCellWithReuseIdentifier("myCell", forIndexPath: indexPath) as! myCell
        // cell.descrption is an UILabel
        cell.description.text = newText
        return cell
    }

and

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
        return CGSizeMake(collectionView.bounds.width*0.95, collectionView.bounds.height/4)       
    }

My question is:

newText is acquired from the web. So it's dynamically changed. After the cell's text is set to newText, how should I adjust the label so that it has the right size to fit "newText" and how should I adjust the cell's size and display it on the screen?

I noticed that sizeForItemAtIndexPath() is invoked before cellForItemAtIndexPath(). Therefore, I can't calculate the size for nextText within sizeForItemAtIndexPath().

1

There are 1 best solutions below

3
On BEST ANSWER

Its a great way to check the what text size would be in sizeForItemAtIndexPath(), as you already know that sizeForItemAtIndexPath() is invoked before cellForItemAtIndexPath() you can have a dummy cell having same information. e.g you may refer to my code which i used in UITableView and implement according to your requirement.

override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
    var myLabel:UILabel!
    var labelText = myTextArray[indexPath.row]
    var constraint = CGSizeMake(662, MAXFLOAT);
    var attributes = NSDictionary(dictionary: [UIFont(descriptor: UIFontDescriptorSizeAttribute, size: 12):NSFontAttributeName])
    var textSize:CGRect = NSString(string: labelText).boundingRectWithSize(constraint, options: NSStringDrawingUsesLineFragmentOrigin, attributes: attributes, context: nil)
    myLabel.text = labelText
    return myLabel.frame.size.height
}

you can do same to achieve size in UICollectionView as both share same inheritance. so there would be no problem. Even you can return custom height depending upon the number of characters in your text. like

override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
    var myLabel:UILabel!

    var labelText = myTextArray[indexPath.row]
    if count(labelText) > 0 && count(labelText) <30
        return 40;
    else if count(labelText)>31 && count(labelText)<60
        return 70;
    //and so on
}