IOS auto layout: отображение ячейки только после обновления ее содержимого

Я использую автоматический макет и показываю таблицу с настраиваемыми динамическими ячейками. В основном таблица отображает чат между двумя лицами. Таким образом, текстовое сообщение меняется для каждой ячейки.

Проблема в том, что первые ячейки отображаются, а затем в течение секунды, ее содержимое изменяется. Это хорошо видно и выглядит плохо.

Смотрите изображения ниже, чтобы понять, как они выглядят до и после изменения размера.

Перед изменением размера:

enter image description here

После изменения размера:

enter image description here

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

Я попытался сделать код ниже, чтобы отобразить ячейку contentView после ее отображения. Но это не работает.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
   // At the begining
    cell.contentView.hidden = NO;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ...
    // Before returning cell
    cell.contentView.hidden = YES;
    return cell;
}

Есть ли способ отложить отображение ячейки до тех пор, пока она не будет изменена в соответствии с их содержимым?

ОБНОВЛЕНИЕ:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    chatCell *cell = (chatCell *)[tableView dequeueReusableCellWithIdentifier:CHAT_CELL_IDENTIFIER];

        cell.textString.text = ...;
        cell.textString.frame = ...;
        cell.timeLabel.text = ...;                                             // set timeLabel to display date and time

        cell.userLabel.text = ...;       // set userLabel to display userName

        if (displaying cell where message is sent by user)
        {
            // Set image for sender
            cell.chatCellBackground.image = [[UIImage imageNamed:@"bubbleMine.png"] stretchableImageWithLeftCapWidth:STRETCHED_WIDTH topCapHeight:STRETCHED_HEIGHT];

            cell.chatCellBackground.frame = ...;

        }
        else
        {
            // set bubble for receiver
            cell.chatCellBackground.image = [[UIImage imageNamed:@"bubbleSomeone.png"] stretchableImageWithLeftCapWidth:STRETCHED_WIDTH topCapHeight:STRETCHED_HEIGHT];

            cell.chatCellBackground.frame = ...;
        }
    }

    [cell setNeedsLayout];
    [cell layoutIfNeeded];
    return cell;
}

Ответ 1

Я добавил ниже метод в пользовательский UITableViewCell класс.

- (void)layoutSubviews
{
    [super layoutSubviews];
    CGFloat maxTextWidth = [UIScreen mainScreen].bounds.size.width * 0.40;
    self.userLabel.preferredMaxLayoutWidth = maxTextWidth;
    self.chatMessage.preferredMaxLayoutWidth = maxTextWidth;
    self.timeLabel.preferredMaxLayoutWidth = self.timeLabel.frame.size.width;
    [super layoutSubviews];
}

Я также обнаружил, что возвращение точно правой высоты ячейки в

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Метод

имеет решающее значение.

Подсказка:

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

Yoy может проверить, является ли высота неправильной, добавив/удалив постоянное значение до высоты (переменной), которую вы вычисляете для ячейки.