Трюки для покращення продуктивності прокрутки iPhone UITableView?


89

У мене є зручне подання, яке завантажує досить великі зображення в кожну комірку, а висота комірки змінюється залежно від розміру зображення. Ефективність прокрутки гідна, але іноді може бути відхиленою.

Я знайшов ці поради, які знайшов у блозі FieryRobot:

скляна прокрутка-з-корисним видом

більш склоподібне прокручування з корисним видом

Хтось має якісь поради щодо покращення ефективності прокрутки uitableview?


Якщо вам потрібно кешувати висоти комірок (які можуть бути дорогими для обчислення і також часто використовуються), я навів приклад. Використовуйте це лише в тому випадку, якщо це підходить для вашої програми. stackoverflow.com/questions/1371223/…
Пол де Ланге

Відповіді:


156
  1. Кешувати висоту рядків (подання таблиці може часто запитувати це)
  2. Створіть кеш нещодавно використовуваного кешу для зображень, що використовуються в таблиці (і анулюйте всі неактивні записи, коли отримаєте попередження про пам'ять)
  3. Намалюйте все, що UITableViewCellє, drawRect:якщо можливо, уникайте підпрограми будь-якою ціною (або якщо вам потрібна стандартна функціональність доступності, перегляд вмісту drawRect:)
  4. Зробіть свій UITableViewCellшар непрозорим (те саме стосується і перегляду вмісту, якщо у вас є)
  5. Використовуйте функцію reusableCellIdentifier, як рекомендовано UITableViewприкладами / документацією
  6. Уникайте градієнтів / ускладнених графічних ефектів, які не заздалегідь вписуються в UIImages

5
Крім того, завантажені зображення слід зменшити до розміру imageView перед тим, як відображати їх у комірці!
Zoltán Matók

4
До цієї відповіді я хотів би додати один свій досвід за останні кілька років - наявність прозорих комірок, мабуть, ніколи не є причиною поганої продуктивності прокрутки. У нас є програма з ДУЖЕ складними клітинками (20+ підпроглядів), і вона прозора для показу фону. За належних оптимізацій прозорість не впливає навіть на 3GS. Насправді найбільше сповільнювало те, що завантажувало перо, перш ніж було достатньо комірок, щоб зняти чергу з подання таблиці. Якщо ви використовуєте підпрогляди, просто переконайтеся, що у вас є ефективні ієрархії, і вам не потрібно використовувати drawRect.
Accatyyc

@Accatyyc, схоже, у мене така сама проблема. Існує невелике відставання, коли недостатньо комірок для зняття з черги, коли 3-4 комірки скидаються з черги, тоді прокрутка стає плавною. Чи є спосіб попереднього завантаження комірок, щоб їх можна було скинути з черги, а не завантажувати файли NIB під час прокрутки?
Тіоа

@Tiois Звичайно, є. Вам потрібно скористатися старим способом зняття з черги комірок (не реєструйте класи / перо, але створюйте їх, якщо dequeueCellWithIdentifier: повертає нуль). Таким чином ви можете створити набір комірок ще до того, як вигляд таблиці навіть існує, наприклад, створивши 20 з них раніше. Потім замість того, щоб створювати нові в cellForRowAtIndexPath :, ви спочатку витягуєте їх із власного кешу, поки вони не порожні.
Accatyyc

Я використовую UICollectionView і стикаюся з тією ж проблемою. У моєму користувальницькому файлі ніб комірки. Я використовую кілька підпрограм, включаючи UIwebView та UIImageView всередині вертикального UIstackView. коли я прокручую свій список, повторно використані клітинки займають значний час, щоб відрегулювати свій розмір, і прокрутка виглядає дуже різкою.
Мансуу ....

40
  1. Якщо ви підкласуєте UITableViewCell, не використовуйте Nib, замість цього напишіть його в коді. Це набагато швидше, ніж завантаження файлів Nib.
  2. Якщо ви використовуєте зображення, переконайтеся, що ви кешуєте їх, щоб вам не потрібно було завантажувати з файлу більше одного разу для кожного (якщо у вас є пам’ять - ви здивуєтеся, скільки місця займають зображення).
  3. Зробіть якомога більше елементів непрозорими. Так само, намагайтеся не використовувати зображення із прозорістю.

3
не хвилюйся ... це були тролі. чудова відповідь!
Steav

79
Голоси проти були, мабуть, тому, що "уникати перо" - погана порада для підвищення ефективності. Якщо ви використовуєте клітинки повторно, клітини при прокрутці взагалі не відновлюються з периметрів.
Стівен Фішер

6
Пікселі еквівалентні швидкості або трохи швидші на основі досліджень "Какао з любов'ю". cocoawithlove.com/2010/03/…
MaxGabriel

@Steven Fisher, використовуючи Nib, може бути повільнішим, коли таблиці розподіляють та вивільняють комірки, наприклад - під час швидкої прокрутки.
Sound Blaster

3
Використання NIB може бути повільнішим під час побудови комірки . Якщо ви використовуєте переробку комірок, для заповнення екрану виділено лише стільки комірок; скажімо, може, максимум 10. Під час прокрутки комірки не створюються. Вони просто використовуються повторно , а не вивільняються та перерозподіляються. І, звичайно, немає жодної вартості розмовляти. Так що ні, це не правильно.
Стівен Фішер

34

Розробник, що стоїть за Tweetie, багато писав про це і має певний код, який демонструє, як це було зроблено для цього додатка. В основному, він / вона виступає за одне користувацьке подання в кожному осередку таблиці та малює його вручну (а не підпрограмує з Interface Builder, серед інших варіантів).

швидка прокрутка в твіті-з-uitableview

Крім того, Apple оновила власний зразок коду для TableView у своїх підручниках з TableViewSuite (можливо, у відповідь на це?)

TableViewSuite


1
Це чудове рішення. Мені просто цікаво, як я можу додати UIBкнопку в cellView? Це намальовано методом drawRect?
Сукіта Удугамасоорія

1
@beno, ваше посилання здається непрацюючим (першим), будь-який шанс докласти руку до оригінальної статті?
apouche

3
Оригінальну статтю можна прочитати тут: web.archive.org/web/20100922230053/http://blog.atebits.com/2008/…
jverdi

додано посилання на веб-архів, оскільки оригінальна версія не існує
Ральф Вілгосс,

1

Вбивця продуктивності №1 для прокрутки UITableView - це малювання тіней на будь-якому шарі перегляду комірки, тому, якщо прокрутка продуктивності має значення, не робіть тіні, якщо це в основному не сповільнює ваш основний потік.

думав, що це потрібно сказати, оскільки жодна з прийнятих відповідей не згадує тіні та шари. : +)


6
якщо проблеми полягають у тіні, додайте ці два рядки коду і все працює ідеально self.layer.shouldRasterize = ТАК; self.layer.rasterizationScale = UIScreen.mainScreen.scale;
Педро Ромао,

0

Будь-яку проблему з UITableViewпродуктивністю прокрутки можна вирішити, використовуючи методи, вже описані в інших відповідях. Однак багато разів млява продуктивність спричиняється чимось по суті помилковим або повторюваним.

Той факт, що UITableViewклітини використовуються повторно, і той факт, що кожна клітина може потребувати власного зображення - разом ускладнює рішення. З того, як це вирішується загальним чином, тут я узагальнюю те, про що слід подбати:

  1. Завантажити дані у джерело даних - з REST / бази даних. Цей крок слід робити у фоновому режимі, з часом використовуючи dispatch_async разом із чергою GCD.
  2. Створювати та ініціалізувати відповідні об'єкти моделі даних та поміщати їх у масив
  3. [tableView reloaddata]
  4. Внутрішній cellForRowAtIndexPathкод включає код, який встановлюватиме дані (текст) із правильного об’єкта моделі даних масиву.
  5. Тепер зображення також можуть бути у формі URL-адреси, тому цей крок може бути трохи химерним через повторне використання комірок, виконане за допомогою подання таблиці. Суть справи полягає в тому, щоб ще раз завантажити зображення з кешу / URL-адреси пристрою за допомогою асинхронної черги, а потім встановити його для виправлення cell.image (незалежно від властивості вашого зображення комірки).

Щоб уникнути проблем, зверніться до цього підручника про ліниве завантаження зображень у поданні таблиці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.