HeightForRowAtIndexPath вызывается для всех строк и сколько строк в UITableView перед проблемами производительности?

Я думал, что прочитал, что для UITableView, что heightForRowAtIndexPath не вызывается во всех строках, а только на тех, которые будут видны. Однако это не то, что я вижу. Я вижу сотни вызовов heightForRowAtIndexPath для простой ситуации с изменением ориентации iPhone, например.

Итак, я предполагаю здесь, что для UITableView с heightForRowAtIndexPath реализовано, он делает (т.е. heightForRowAtIndexPath) вызывается для всех строк (а не только для видимых)... дайте мне знать, если это не совсем корректно.

ВОПРОС: С учетом вышеизложенного, сколько строк в UITableView (где heightForRowAtIndexPath реализовано) вы можете иметь до того, как обычно возникают проблемы с производительностью?

Есть ли способ решения проблем производительности? т.е. установить номинальную/стандартную высоту для каждой строки и не реализовывать heightForRowAtIndexPath, но затем правильно установить каждую высоту строки только тогда, когда она будет отображаться, и установить ее здесь правильно... но какой метод будет делать это?

Ответ 1

Посмотрите раздел обсуждения в tableView:heightForRowAtIndexPath: документации

Метод позволяет делегату указать строки с разной высотой. Если этот метод реализован, возвращаемое значение переопределяет значение, указанное для свойства rowHeight UITableView для данной строки.

При использовании tableView возникают последствия для производительности: heightForRowAtIndexPath: вместо свойства rowHeight. Каждый раз, когда отображается представление таблицы, он вызывает tableView: heightForRowAtIndexPath: в делегате для каждой из его строк, что может привести к значительной проблеме с представлением таблицы, имеющей большое количество строк (приблизительно 1000 или более).

Итак, вы должны использовать свойство rowHeight UITableView. Если вам нужны разные высоты, вам не повезло, потому что вы должны использовать tableView:heightForRowAtIndexPath:.

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

Ответ 2

Думаю, я нашел решение.

В iOS 7 apple появилось несколько новых свойств tableview. Один из них:

tableView:estimatedHeightForRowAtIndexPath:

Итак, если вы указываете примерную высоту строки, например, тогда, когда tableView: heightForRowAtIndexPath: вызывается несколько раз до отображения таблицы, она вызывается только для видимых ячеек таблицы; для остальных ячеек используется расчетная высота.

Вот источник этой информации: https://books.google.gr/books?id=wLaVBQAAQBAJ&pg=PT521&lpg=PT521&dq=heightforrowatindexpath+only+for+the+visible+cells&source=bl&ots=7tuwaMT5zV&sig=h3q8AaFvoCgcrPu2fQchVkIEjwg&hl=en&sa=X&ved=0CEMQ6AEwBWoVChMInLK0xbPuxwIVCbUaCh3_nQWG#v=onepage&q=heightforrowatindexpath%20only%20for%20the%20visible%20cells&f=false

Ответ 3

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

Наконец, я также нашел сотни вызовов heightForRowAtIndexPath и поиск получил мне эту тему. Это действительно раздражает. Производительность здесь уже снижается при отображении 250 элементов. К счастью, ячейки, которые я хочу отображать, теперь имеют одинаковый размер. Но я мог представить, что кто-то хочет отобразить несколько разных ячеек для tableView s > 200 элементами!

ИСПОЛЬЗУЙТЕ ЭТОТ ЯБЛОК!

Приветствия

Ответ 4

Способ повышения производительности в tableViews с большим количеством строк и динамическими высотами ячеек заключается в том, чтобы кэшировать высоту ячеек после их вычисления.

Упрощенный подход для достижения этого - сохранить NSMutableDictionary, в котором ключ является идентификатором записи в ячейке (или любым другим идентификатором, который у вас может быть), а значение равно NSNumber с высотой строки. После того, как высота будет сначала рассчитана, сохраните ее NSMutableDictionary по идентификатору записи. В tableView:heightForRowAtIndexPath и tableView:estimatedHeightForRowAtIndexPath: вы проверяете высоту кеширования в словаре и возвращаете ее, если она найдена. Если не найден, вычислите высоту и сохраните в кеше, прежде чем возвращать высоту.

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

У вас может быть производительность, если вы попытаетесь отобразить 1000 ячеек сразу, как показано в таблице, поскольку это, скорее всего, вызовет метод высоты для каждой строки. Для этого нужно сначала согреть кеш, если это возможно, в фоновом задании, прежде чем сначала отобразить ячейки.