Altura dinâmica do UITableViewCell com número variável de subvisões

eu tenho umUITableViewCell preenchido dinamicamente com dados recuperados de uma fonte remota. Ele possui um número variável de subvisões com base no tipo de item que está sendo representado na célula. Estou calculando dinamicamente o tamanho do conteúdo da célula usando umNSMutableAttributedString e aboundingRectWithSize: método. Pego os valores retornados e calculo umcombinedHeight variável armazenada em umNSMutableDictionary e associado aoindexPath da célula. Tudo funciona bem, mas quando tento usar os valores do dicionário no diretórioheightForRowAtIndexPath: método, ele usa apenas o primeiro conjunto de células visíveis e, depois disso, tudo é 0.

Minha pergunta é como posso dimensionar dinamicamente a célula para conter todas as subvisões. Também estou adicionando uma exibição personalizada ao contentView da célula, que é de largura menor que a célula, para que eu possa alcançar um estilo único que estamos buscando.

Aqui está o meu código:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (areFeedItemsLoaded && feedItems.count > 0 && indexPath.row < feedItems.count)
    {
        CGFloat height = [[_cellHeights objectForKey:[self keyForIndexPath:indexPath]] floatValue];

        return MAX(90, height);
    }
    return 44;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;

    if (areFeedItemsLoaded)
    {
        if (feedItems.count == 0)
        {
            if (indexPath.row == 0)
            {
                cell = [EmptyTableViewCell getBlankCell:tableView];
            }
            else
            {
                EmptyTableViewCell *eCell = [EmptyTableViewCell getEmptyCell:tableView withHeaderText:@"No Recent Activity"];
                [eCell setLinkText:@"Your team's activity on Hudl will appear here." withUrl:nil];
                cell = eCell;
            }
        }
        else if (indexPath.row < feedItems.count)
        {
            FeedItem *item = [feedItems objectAtIndex:indexPath.row];
            cell = [self.tableView dequeueReusableCellWithIdentifier:FeedItemCellIdentifier forIndexPath:indexPath];

            if (cell == nil)
            {
                cell = [[FeedItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:FeedItemCellIdentifier];
            }

            cell.clipsToBounds = YES;

            cell.backgroundColor = [UIColor clearColor];

            CGFloat combinedHeight = 8;

            UIView *customContentView = [cell viewWithTag:customContentTagId];

            if (customContentView == nil)
            {
                customContentView = [[UIView alloc] init];
                customContentView.tag = customContentTagId;
                customContentView.backgroundColor = [UIColor colorWithR:100 g:100 b:100 a:1];
                [cell.contentView addSubview:customContentView];
            }

            customContentView.frame = CGRectMake(50, 0, 270, 70);

            UIImageView *userImage = (UIImageView *)[cell viewWithTag:userImageTagId];

            if (userImage == nil)
            {
                userImage = [[UIImageView alloc] init];
                userImage.tag = userImageTagId;
                [customContentView addSubview:userImage];
            }

            userImage.frame = CGRectMake(8, 8, 45, 45);
            userImage.layer.cornerRadius = CGRectGetWidth(userImage.frame) / 2;
            userImage.layer.masksToBounds = YES;

            NSURL *imageUrl = item.imageSourceUrl;
            [userImage setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:@"default-user.png"]];

            CGFloat minX = CGRectGetMaxX(userImage.frame) + 8;

            UILabel *titleLabel = (UILabel *)[cell viewWithTag:titleTagId];

            if (titleLabel == nil)
            {
                titleLabel = [[UILabel alloc] init];
                titleLabel.numberOfLines = 0;
                titleLabel.textColor = [UIColor colorWithR:204 g:204 b:204 a:1];
                titleLabel.font = [UIFont fontWithName:@"Helvetica" size:14];
                titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
                titleLabel.tag = titleTagId;

                [customContentView addSubview:titleLabel];
            }

            NSString *title = [NSString stringWithFormat:@"%@ %@", item.creatorName, item.title];
            NSMutableAttributedString *titleText = [[NSMutableAttributedString alloc] initWithString:title];

            [titleText addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithR:204 g:204 b:204 a:1] range:NSMakeRange(0, title.length - 1)];
            [titleText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica-Bold" size:14] range:NSMakeRange(0, item.creatorName.length)];
            [titleText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:15] range:NSMakeRange(item.creatorName.length + 1, title.length - item.creatorName.length - 1)];

            titleLabel.attributedText = titleText;

            CGFloat width = CGRectGetWidth(customContentView.frame) - (CGRectGetMaxX(userImage.frame) + 8) - 8;

            width = MIN(width, 200);

            CGSize titleSize = [titleText boundingRectWithSize:CGSizeMake(width, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size;

            titleLabel.frame = CGRectMake(minX, CGRectGetMinY(userImage.frame), ceil(titleSize.width), ceil(titleSize.height));

            combinedHeight += ceil(titleSize.height) + 8;

            UIView *thumbnailsView = [cell viewWithTag:thumbnailTagId];
            UILabel *descriptionLabel = (UILabel *)[cell viewWithTag:descriptionTagId];

            if ([item.feedItemType intValue] == PlaylistFI || [item.feedItemType intValue] == PlaylistAndNotesFI)
            {
                if ([item.uris count] > 0)
                {
                    if (thumbnailsView == nil)
                    {
                        thumbnailsView = [[UIView alloc] init];
                        thumbnailsView.tag = thumbnailTagId;
                        [customContentView addSubview:thumbnailsView];
                    }
                    else
                    {
                        for (UIView *view in thumbnailsView.subviews)
                        {
                            [view removeFromSuperview];
                        }
                    }

                    thumbnailsView.frame = CGRectMake(minX, CGRectGetMaxY(titleLabel.frame) + 8, width, 40);

                    combinedHeight += 48;

                    for (int i = 0; i < 3 && i < item.uris.count; i++)
                    {
                        NSURL *url = [item.uris objectAtIndex:i];
                        UIImageView *imageView = [[UIImageView alloc] init];
                        int x = i * 60 + i * 8;
                        imageView.frame = CGRectMake(x, 0, 60, 40);

                        [imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:@"soft-dark-grad.png"]];
                        [thumbnailsView addSubview:imageView];
                    }
                }

                if (descriptionLabel == nil)
                {
                    descriptionLabel = [[UILabel alloc] init];
                    descriptionLabel.tag = descriptionTagId;
                    descriptionLabel.font = [UIFont systemFontOfSize:14];
                    descriptionLabel.textColor = [UIColor colorWithR:204 g:204 b:204 a:1];
                    descriptionLabel.numberOfLines = 0;
                    descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;

                    [customContentView addSubview:descriptionLabel];
                }

                NSMutableAttributedString *descriptionText = [[NSMutableAttributedString alloc] initWithString:item.descriptionText];
                [descriptionText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:14] range:NSMakeRange(0, item.descriptionText.length)];

                descriptionLabel.attributedText = descriptionText;

                CGSize descriptionSize = [descriptionText boundingRectWithSize:CGSizeMake(width, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size;

                descriptionLabel.frame = CGRectMake(minX, CGRectGetMaxY(thumbnailsView.frame) + 8, ceil(descriptionSize.width), ceil(descriptionSize.height));

                combinedHeight += ceil(descriptionSize.height) + 8;
            }
            else
            {
                if (thumbnailsView != nil)
                {
                    [thumbnailsView removeFromSuperview];
                }

                if (descriptionLabel != nil)
                {
                    [descriptionLabel removeFromSuperview];
                }
            }

            UILabel *messageLabel = (UILabel *)[cell viewWithTag:messageTagId];

            if ([item.feedItemType intValue] == MessageFI)
            {
                if (messageLabel == nil)
                {
                    messageLabel = [[UILabel alloc] init];
                    messageLabel.tag = messageTagId;
                    messageLabel.font = [UIFont systemFontOfSize:14];
                    messageLabel.textColor = [UIColor colorWithR:204 g:204 b:204 a:1];
                    messageLabel.numberOfLines = 0;
                    messageLabel.lineBreakMode = NSLineBreakByWordWrapping;

                    [customContentView addSubview:messageLabel];
                }

                NSMutableAttributedString *messageText = [[NSMutableAttributedString alloc] initWithString:item.message];
                [messageText addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Helvetica" size:14] range:NSMakeRange(0, item.message.length)];

                CGSize messageSize = [messageText boundingRectWithSize:CGSizeMake(width, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size;

                messageLabel.frame = CGRectMake(minX, CGRectGetMaxY(titleLabel.frame) + 8, ceil(messageSize.width), ceil(messageSize.height));
                messageLabel.attributedText = messageText;

                combinedHeight += ceil(messageSize.height) + 8;
            }
            else
            {
                if (messageLabel != nil)
                {
                    [messageLabel removeFromSuperview];
                }
            }

            if ([item.feedItemType intValue] == PlaylistFI || [item.feedItemType intValue] == PlaylistAndNotesFI ||
                [item.feedItemType intValue] == ArticleFI)
            {
                cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
                cell.selectionStyle = UITableViewCellSelectionStyleBlue;
            }
            else
            {
                cell.accessoryType = UITableViewCellAccessoryNone;
                cell.selectionStyle = UITableViewCellSelectionStyleNone;
            }

            [_cellHeights setObject:@(combinedHeight) forKey:[self keyForIndexPath:indexPath]];

            CGRect frame = customContentView.frame;
            frame.size.height = MAX(70, combinedHeight);
            customContentView.frame = frame;
        }
        else if (!requestFailed)
        {
            cell = [LoadingTableViewCell getLoadingCell:tableView];
        }
        else
        {
            cell = [ErrorTableViewCell getErrorCell:tableView];
        }
    }
    else
    {
        cell = (indexPath.row == 0 || indexPath.row < feedItems.count) ? [EmptyTableViewCell getBlankCell:tableView] : [LoadingTableViewCell getLoadingCell:tableView];
    }
    return cell;
}

- (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath
{
    if ([indexPath class] == [NSIndexPath class]) {
        return indexPath;
    }
    return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
}

questionAnswers(1)

yourAnswerToTheQuestion