Динамическая высота UITableViewCell с переменным количеством подпредставлений

у меня естьUITableViewCell динамически заполняется данными, полученными из удаленного источника. Он имеет переменное количество подпредставлений в зависимости от типа элемента, представляемого в ячейке. Я динамически рассчитываю размер содержимого ячейки с помощьюNSMutableAttributedString иboundingRectWithSize: метод. Я беру возвращенные значения и вычисляюcombinedHeight переменная, которая хранится вNSMutableDictionary и связано сindexPath клетки. Это все работает нормально, но когда я пытаюсь использовать значения из словаря вheightForRowAtIndexPath: метод, он использует только первый набор видимых ячеек, и после этого все равно 0.

Мой вопрос заключается в том, как я могу динамически изменить размер ячейки, чтобы вместить все подпредставления. Я также добавляю настраиваемое представление в contentView ячейки, ширина которого меньше, чем ячейка, чтобы я мог создать уникальный стиль, к которому мы стремимся.

Вот мой код:

    - (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];
}

Ответы на вопрос(1)

Ваш ответ на вопрос