UICollectionViewCell height based on label size

1.1k views Asked by At

I have a view which contains UICollectionView that loads external cellnib file of UICollectionViewCell. I have the data showing properly just the way I want. I want to keep the cell height based on the textlabel inside it but I am not sure what am I missing in the code below. I have tried going through answers but it did not make much sense on how to tackle it. Please help. Thanks in advance.

  - (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MyCollectionViewCell *cell =  (MyCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@" mycell" forIndexPath:indexPath];

    NSString *string = cell.lblContact.text;
    CGSize size = [self getLabelSize:string];
    NSLog(@"%f and %f",size.width ,size.height);

   return cell;
}

- (CGSize)getLabelSize:(NSString *)string {

    UIFont *updatedFont = [UIFont fontWithName:@"myFont" size:18.0];
    CGRect rect = [string boundingRectWithSize:(CGSize){maxWidth, CGFLOAT_MAX} options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName: updatedFont } context:nil];
    return rect.size;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    CGSize retval = CGSizeMake(collectionView.frame.size.width, 75);
    return retval;
}

- (UIEdgeInsets)collectionView: (UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section 
{
     return UIEdgeInsetsMake(0, 0, 0, 0);
}
2

There are 2 answers

0
Milan Shah On

I found the solution. I created a string in sizeForItemAtIndexPath that was getting a value out from the same place as cell.lblContact.text.

MyObject *mc = (MyObject *) [contactArray objectAtIndex:indexPath.row];
NSString *myString = mc.contactName;
CGSize size = [self getLabelSize:myString];
NSLog(@"%@", myString);
NSLog(@"%f", size.height);

if (myString.length > 25) {
    CGSize retval = CGSizeMake(collectionView.frame.size.width, size.height);
    [collectionView layoutIfNeeded];
    return retval;
} else {
    CGSize retval = CGSizeMake(collectionView.frame.size.width, 75);
    return retval;
}
3
jrisberg On

You retrieve the size of the label, but it looks like you are using a different CGSize to size the label. Instead of CGSizeMake(collectionView.frame.size.width, 75), try keeping a reference to the size of the label and using that as the return value:

- (UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    MyCollectionViewCell *cell =  (MyCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@" mycell" forIndexPath:indexPath];

    NSString *string = cell.lblContact.text;
    self.labelSize = [self getLabelSize:string];

    return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return self.labelSize;
}

EDIT

Have you tried accessing the frame of the label and storing it?

self.labelSize = CGSizeMake(self.myCell.frame.size.width, self.myCell.frame.size.height);