Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a view controller which has a UITableView instance and uses auto layout constraints to render it. I would like to have variable cell heights in this table view. I do not want to calculate the cell height myself because I have a complex cell content composed of several labels and images that can vary from cell to cell. I do believe it is possible to let the auto-layout cell to resize itself so it contains all its subviews (i.e. using sizeToFit method of labels after assigning text to them?).

I have a custom cell class that uses visual constraints format of auto layout to position its subviews. I tried to incorporate the method proposed in here and its sample implementation here. When I initialize the table view, I create an array with the equal length of my data rows and calculate each row's height by assigning values to a prototype cell of type MyCustomCell and retrieve its height using this

[cell systemLayoutSizeFittingSize:UILayoutFittingExpandedSize].height

and storing it in the heights array so to use it later in heightForRowAtIndexPath method of table view to retrieve the correct cell height for individual cells.

Doing all these, however, I end up with an unreadable exception NSInternalInconsistencyException in xCode with "Cannot find an outgoing row head for incoming head MyCustomCell:0xa8a1430.Width, which should never happen."

Here is the initialization of the subviews in my custom cell:

    _titleLabel = [[UILabel alloc] init];
    _titleLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
    _titleLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
    _titleLabel.backgroundColor = [UIColor clearColor];
    _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:19];
    _titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    [self.contentView addSubview:_titleLabel];

    _summaryLabel = [[UILabel alloc] init];
    _summaryLabel.font = [TSTheme boldThemeFontOfSize:TSThemeFontSizeSmall];
    _summaryLabel.backgroundColor = [UIColor clearColor];
    _summaryLabel.textColor = [[TSTheme sharedTheme] darkTextColor];
    _summaryLabel.translatesAutoresizingMaskIntoConstraints = NO;
    _summaryLabel.numberOfLines = 0;
    _summaryLabel.preferredMaxLayoutWidth = 250.0f; // required for text wrapping
    _summaryLabel.font = [UIFont fontWithName:@"Georgia" size:14];
    _summaryLabel.lineBreakMode = NSLineBreakByWordWrapping;
    [self.contentView addSubview:_summaryLabel];

    _thumbnailView = [[UIImageView alloc] init];
    _thumbnailView.translatesAutoresizingMaskIntoConstraints = NO;

    [self.contentView addSubview:_thumbnailView];

and the constraints for my custom cell are as follow

NSDictionary *views = NSDictionaryOfVariableBindings(_titleLabel, _summaryLabel, _thumbnailView);
NSDictionary *metrics = @{@"margin": @"5"};

[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView(<=60)]-(margin)-[_titleLabel]-(margin)-|"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];

[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_thumbnailView]-(margin)-|"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];


[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[_titleLabel]-(0)-[_summaryLabel]"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];


[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[_thumbnailView]-(margin)-[_summaryLabel]-(margin)-|"
                                                                         options:0
                                                                         metrics:metrics
                                                                           views:views]];
share|improve this question

2 Answers 2

I encountered this when I used a table view cell that was added directly as a prototype to a UITableView in a storyboard and used dequeueReusableCellWithIdentifier: to get the cell for caching the heights.

If I moved the cell into a separate nib then it instantiated the cell for determining heights directly from the nib the problem went away.

Then you can register the nib with the UITableView. Hope this helps.

share|improve this answer

I used this code to calculate dinamically the hieght of a row because the content of each one was different:

-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ // Hacer que el tamaño de la celda sea variable dependiendo del tamaño del texto a mostrar

    NoticiaAsignatura_DTO *rowData = [[NoticiaAsignatura_DTO alloc] init];

    rowData = [self.listaNoticias objectAtIndex:[indexPath row]];

    NSString *text = rowData.title;
    text = [text stringByAppendingString:@"\n"];
    text = [text stringByAppendingString: rowData.publish_date_ansi];
    text = [text stringByAppendingString:@"\n\n"];
    text = [text stringByAppendingString:rowData.content];
    text = [text stringByAppendingString:@"\n\n"];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){

        CGSize constraint = CGSizeMake(700,200000.0);
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
        return size.height + (CELL_CONTENT_MARGIN * 2);
    }
    else{
        CGSize constraint = CGSizeMake(300,200000.0);
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE_PHONE] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];
        NSLog(@"Size: %f ", size.height);
        return size.height + (CELL_CONTENT_MARGIN * 2);
    }

}

Hope it helps.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.