6

I have an iOS app with a UICollectionView which presents cells horizontally. In each of the cells, I have added one simple label (for now). These labels are showing names, sometimes the names are short and thats fine... but.... sometimes the names are long and are thus cut off because they cannot fit properly within the width of the collection view cell.

Is there a way to adjust the width of the cell/label dynamically so that the name text will be shown properly?

I was experimenting using this method:

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(106.f, 60.f);
}

But I have two main problems with the above method:

  1. How do I access the cell label from this method? (So that I can get its height).
  2. How do I actually figure out what the width of the cell/label needs to be?

Thanks for your time,

Dan

Supertecnoboff
  • 6,406
  • 11
  • 57
  • 98
  • try this link http://stackoverflow.com/questions/23134986/dynamic-cell-width-of-uicollectionview-depending-on-label-width – sandy Oct 05 '15 at 10:30

4 Answers4

0

You can't access to the Label, but you can access to the data that you use to populate it. With that you can get the height and width of your label:

CGRect labelRect = [text
                boundingRectWithSize:CGSizeMake(MAX WIDTH OF YOUR LABEL, CGFLOAT_MAX)
                options:NSStringDrawingUsesLineFragmentOrigin
                attributes:@{
                 NSFontAttributeName : [FONT OF YOUR LABEL]
                }
                context:nil];
  • This doesn't work for me, it just crashes. Also for ```[FONT OF YOUR LABEL]``` is it expecting a ```UIFont``` object? – Supertecnoboff Oct 05 '15 at 11:49
  • Actually this does work for me now. But I am still struggling to get it to work all the time. Sometimes the width it provides is a bit too much. – Supertecnoboff Oct 05 '15 at 14:23
0

I have done same thing in TableView - hope you can use this logic for collectionView

celllabelWidth - width of the Cell, you can get it from cellForItemAtIndexPath
celllabelWidth = cell.lblEvent.frame.size.width;

- (CGFloat)findHeightForText:(NSString *)text havingWidth:(CGFloat)widthValue andFont:(UIFont *)font {
        CGSize size = CGSizeZero;
        if (text) {
            //iOS 7
            CGRect frame = [text boundingRectWithSize:CGSizeMake(widthValue, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName:font } context:nil];
            size = CGSizeMake(frame.size.width, frame.size.height);
        }
        return size.height;
    }

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat heightOfRow = 86.0;
    NSString *yourBlog = [[self.arrevents objectAtIndex:indexPath.row ] valueForKey:@"info"];
    heightOfBlog = [self findHeightForText:yourBlog havingWidth:celllabelWidth andFont:[UIFont fontWithName:@"HelveticaNeue" size:14.0]];
    heightOfRow += heightOfBlog + 10;
(long)indexPath.row,heightOfRow);
    return heightOfRow;
}

Hope for the best :)

Sushil Sharma
  • 2,321
  • 3
  • 29
  • 49
Himanshu padia
  • 7,428
  • 1
  • 47
  • 45
0

I have done same thing in collection view with following code :

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    CGSize size1 = CGSizeMake(MAX_WIDTH_OF_STRING, [self height:YOUR_STRING];
    return size1;
}

-(float)height :(NSString*)string
    {
        UIFont *newFont = [[Util sharedUtil] fontOfType:FONT_HELVETICA_LT bold:NO size:INTERFACE_IS_PHONE?12:FONT_SIZE_LARGE_CELL];

        NSDictionary *arialdict = [NSDictionary dictionaryWithObject:newFont forKey:NSFontAttributeName];

        NSMutableAttributedString *message = [[NSMutableAttributedString alloc] initWithString:string attributes:arialdict];

        NSAttributedString *attributedText = message;
        CGRect rect = [attributedText boundingRectWithSize:(CGSize)     
                       {INTERFACE_IS_PHONE?135:220, MAXFLOAT}
                       options:NSStringDrawingUsesLineFragmentOrigin
                        context:nil];
            //you need to specify the some width, height will be calculated
            CGSize requiredSize = rect.size;
        return MAX(requiredSize.height,INTERFACE_IS_PHONE?20:30);
    }

Hope it help you.

riddhi
  • 316
  • 2
  • 16
0

Thanks to everyone for posting, in the end the solution that worked for me was a mix of all your solutions and a bit of extra "tinkering":

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    // Get the user name and profile name strings.
    NSString *user_label = [NSString stringWithFormat:@"%@", [user_data[indexPath.row] objectAtIndex:0]];
    NSString *name_label = [NSString stringWithFormat:@"%@", [user_data[indexPath.row] objectAtIndex:1]];

    // Calculate the contact text widths.
    NSDictionary *attributes = @{NSFontAttributeName:[UIFont fontWithName:@"SFUIDisplay-Thin" size:20.0f]};
    CGRect rect = [user_label boundingRectWithSize:CGSizeMake(MAXFLOAT, 60) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];
    CGRect rect_two = [name_label boundingRectWithSize:CGSizeMake(MAXFLOAT, 60) options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil];

    // Add the other cell objects width to
    // the biggest calculated text width.
    CGFloat row_width = 0;

    if (rect.size.width > rect_two.size.width) {
        row_width = (rect.size.width + 55);
    }

    else {
        row_width = (rect_two.size.width + 55);
    }

    // Only return the generated width if
    // it is bigger than the original width.

    if (row_width > 106) {
        return CGSizeMake(row_width, 60.f);
    }

    else {
        return CGSizeMake(106, 60.f);
    }
}
Supertecnoboff
  • 6,406
  • 11
  • 57
  • 98