Как сообщить моему UITableViewCell о "автоматическом изменении размера" при изменении его содержимого?

В моей cell.xib у меня есть ярлык со всеми ограничениями. Я установил эту метку в lines = 0 и line-break = word wrap. Затем я делаю это с моим TableView:

self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 100.0

Все отлично работает, и мой UITableViewCell - это авто-высота. Если текст длинный, то мой tableView разумно вычисляет размер.

Проблема заключается в следующем: как я могу сообщить UITableView "пересчитать" размер после изменения содержимого в ячейке?

Моя ячейка могла называть ее делегатом, и в этом деле я хотел бы, чтобы TableView повторно рисовал высоту.

Прямо сейчас контент в моих ячейках меняется постоянно, но высота ячейки никогда не меняется.

Ответ 1

Существует документированный способ сделать это. См. Документацию UITableView.beginUpdates():

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

Итак, правильное решение:

tableView.beginUpdates()
tableView.endUpdates()

Также обратите внимание, что есть функция, которая не документирована - вы также можете добавить обработчик завершения анимации обновления:

tableView.beginUpdates()
CATransaction.setCompletionBlock {
   // this will be called when the update animation ends
}

tableView.endUpdates()

Тем не менее, протектив легко, он не документирован (но он работает, потому что UITableView использует CATransaction для анимации).

Ответ 2

Я нашел, что лучший способ заставить его проверить высоту, чтобы позвонить, после того, как было сделано какое-либо изменение текста, в порядке:

self.tableView.beginUpdates()
self.tableView.endUpdates()

Это заставляет tableView проверять высоты для всех видимых ячеек, и это приведет к необходимости внесения изменений по мере необходимости.

Ответ 3

Вы можете получить автоматическую высоту ячейки по этому коду

tableView.beginUpdates()
// add label text update code here 
// label.numberOfLines = label.numberOfLines == 0 ? 1 : 0
tableView.endUpdates()

Ниже приведена ссылка на это решение с демонстрацией:

GitHub-RayFix-MultiLineDemo

Ответ 4

Я думаю, что самым простым решением является перезагрузка этой конкретной ячейки. Например:

- (void)yourDelegateMethodOfCell:(UITableViewCell *)cell {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    //If cell is not visible then indexPath will be nil so,
    if (indexPath) {
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
}

Ответ 5

Я получил ваше мнение, и раньше я встречал проблему.
Ваша ячейка находится в AutoLayout, и вы хотите, чтобы ячейка менялась сама по себе. Для этого рекомендуется ответить на этот вопрос: использование автоматической компоновки в UITableView для динамических раскладок ячеек и переменных высот строк, поэтому мы больше об этом не говорим.

Поэтому здесь мы сосредоточимся на вашей проблеме.

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

Здесь идет пункт: Как изменение метки информирует ячейку о необходимости обновления?

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

И я думаю, что это сработает!

Ниже приведен подробный шаг:
1. Мы устанавливаем ограничения для подзонов соты. (Я думаю, это было сделано)
2. Одна из высоты ярлыка сама по себе изменяется (я думаю, это тоже было сделано)
3. Мы получаем новую высоту метки и обновляем ограничение высоты для метки (что мы должны делать)

Ответ 6

Кажется, вы хотели перезагрузить определенную ячейку/ячейки на основе изменений контента

Здесь у нас есть пара вариантов

1) Необходимо перезагрузить весь вид таблицы.

или иначе

2) Перезагрузка определенных ячеек/ячеек на основе изменений содержимого.

Но предпочтительным вариантом будет перезагрузка конкретной ячейки,

Почему, поскольку, когда вы попросили экземпляр UITableView перезагрузить пару ячеек, tableview запросит свой источник данных (-tableView: cellForRowAtIndexPath :) для получения обновленного контента, так что перезагруженные ячейки будут иметь обновленный размер и обновленный контент.

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

Надеюсь, это поможет! Счастливое кодирование :)

Ответ 7

Взгляните на этот ответ: использование автоматической компоновки в UITableView для динамических раскладок ячеек и переменных высот строк

Как добиться динамического размера ячейки, здесь очень подробно описано.

В качестве предложения для тестирования попробуйте добавить setNeedsLayout в:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

или

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath 

Ответ 8

Вы можете изменить размер своей ячейки, выполнив только метод ниже

 - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}