Обычно вам требуется одинаковое использование памяти и шаблон повторного использования ячеек, который Cocoa предоставляет для ячеек таблицы, поэтому используйте UITableViewHeaderFooterView
. В viewDidLoad:
вызове tableView.registerClass(UITableViewHeaderFooterView.classForCoder(), forHeaderFooterReuseIdentifier:"Header")
Теперь вы можете из очереди этих взглядов по требованию в ваших методах делегата, такие как:
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView: UITableViewHeaderFooterView
if let reusedView = tableView.dequeueReusableHeaderFooterViewWithIdentifier("Header") as? UITableViewHeaderFooterView {
// Remove the existing contents of the reused view
map(reusedView.contentView.subviews) {
$0.removeFromSuperview()
}
headerView = reusedView
} else {
headerView = UITableViewHeaderFooterView(reuseIdentifier:"Header")
}
let imageView = ... // Set up image view
let label = ... // Set up label
headerView.contentView.addSubview(imageView)
headerView.contentView.addSubview(label)
return headerView
}
какао распоряжаются и повторно используете эти представления заголовка, как нужно сейчас.
Эта реализация намного более прямолинейна, если вы используете подкласс UITableViewHeaderFooterView
и добавляете свои свойства изображения и метки (тогда вам не нужно будет удалять, а затем добавлять объекты в виде объекта, которые будут заменены, только заменить их по имени). Также, если вы создаете наконечник для своего класса или используете ячейку просмотра таблицы для просмотра через раскадровку, dequeuing никогда не вернет нуль.
Поскольку вы упоминаете, что у вас могут быть «бесконечные ячейки», может быть, вы беспокоитесь о том, чтобы хранить слишком много вашего источника данных в памяти (возможно, у вас есть огромное количество больших изображений для этих изображений). В этом случае вам нужно настроить какой-то кеш. Взгляните на NSCache
, если вы доберетесь до этой точки. Нет необходимости реализовывать свой собственный кеш.
По просьбе OP я подробно расскажу о том, как эта система dequeue работает в Cocoa. Вероятно, у вас есть аналогичный код в вашем делекторе tableView:cellForRowAtIndexPath:
. Представьте, что ваш пользователь прокручивается вниз через ваш вид таблицы. У вас есть ячейки и заголовки, выходящие за пределы экрана в верхней части табличного вида, и новые, появляющиеся внизу таблицы. Все эти ячейки имеют аналогичный формат. Теперь предположим, что Cocoa не делает ничего особенного (без очереди ячеек). Исчезающие клетки будут освобождены, и появляющиеся ячейки будут созданы с нуля. Вместо этого Cocoa пытается быть эффективным и держит очередь этих ячеек/заголовков под рукой. Он не будет создавать ничего больше, чем нужно отображать на экране в любой момент времени. Когда одна из ячеек выходит за пределы экрана, она помещает ее в очередь, и затем эта ячейка становится доступной для удаления из очереди (выведенной из очереди) позже вами. Когда вы деактивируете ячейку или заголовок (вы запрашиваете ее в соответствии со строкой идентификатора повторного использования), она даст вам точный вид, который вышел на экран (или один из них). Как только вы его получите, настройте его по своему усмотрению. Да, в приведенном выше коде вам необходимо создать UIImageView
и UILabel
(я объясню, как вы можете и должны делать еще лучше ниже), но основные UIView
и любые виды декорирования, которые не нужно менять, будут все еще там (нет вычислительных затрат на повторное использование их). Таким образом, в основном Cocoa помогает вам перерабатывать эти взгляды, делая вещи очень эффективными и безопасными.
Вы заметите, что, когда код выше пытается удалить ячейку, он находится в операторе if let
, который проверяет, является ли он нолем. Это важно, потому что, если вы просто загружаете представление в таблицу, у него нет ячеек/представлений в очереди, чтобы дать вам, поэтому, если он равен нулю, вы создаете новый вид с нуля. Когда вы создаете экземпляр, вы даете ему строку идентификатора повторного использования. Если это представление выходит за пределы экрана позже, Cocoa знает, чтобы поместить его в свою специальную очередь, чтобы позже вернуться к вам. Однако, как я заметил выше, если ваше представление загружается из ниба или раскадровки, dequeuing всегда будет возвращать non-nil. Еще одна детальная информация о загрузке с наконечника, вы хотите зарегистрировать идентификатор повторного использования, используя метод registerNib:forHeaderFooterReuseIdentifer:
UITableView
.
Теперь вы можете увидеть, как Cocoa обрабатывает эти ячейки/просматривать очень эффективно, не требуя, чтобы вы создавали новые представления, когда ваш пользователь прокручивает представление таблицы, вы можете немного разочароваться в моем коде выше, который все еще удаляет все старых представлений и создания новых UIImageView
s и UILabel
s, и действительно, вы должны быть разочарованы. Рекомендуемый способ обойти это путем подкласса UITableViewHeaderFooterView
, или вы действительно можете подклассы UIView
. Создайте свойство для imageView и метки. Теперь вместо того, чтобы уничтожить подпункты со старым контентом и затем снова создать эти представления, просто замените их содержимое новым соответствующим контентом (imageView.image = newUIImage
и label.text = newString
). Верьте или нет, это сэкономит массу вычислений. UIView
s - несколько дорогостоящий для создания. Неаккуратная (хотя и потенциально более гибкая) альтернатива подклассу будет заключаться в том, чтобы поместить теги в эти представления, которые вы хотите вставить, используя свойство tag
, а затем получить ссылку на эти представления позже, используя headerView.viewWithTag(anInt)
.
И я ненавижу, чтобы все эти разговоры о заголовках были зря, но я сделаю последнее замечание. Я заметил, что вы говорите, что каждая ячейка имеет свой собственный заголовок. Если это так, вам, вероятно, будет лучше, просто создав одну большую ячейку таблицы (поместите содержимое заголовка выше обычного содержимого ячейки таблицы). Вы можете пропустить использование заголовков все вместе. Однако я не знаю всего, что происходит в вашем приложении, поэтому я просто позволю вам судить об этом.
Удачи вам @ Анкуш! Знание веревок вокруг UITableView
- отличное умение iOS, которое, я уверен, вы найдете полезным в будущем!
Но что, если мне нужны бесконечные ячейки? Поскольку каналы в питающей сети не ограничены. – Ankush
@Ankush Я добавил небольшую вариацию, которая повторно использует не более 20 разных заголовков, чтобы дать вам представление. – hennes
Спасибо, я ценю это :) – Ankush