Вопрос прост: как вы загружаете кастом UITableViewCell
из файлов Xib? Это позволяет вам использовать Interface Builder для проектирования ваших ячеек. Ответ очевидно не прост из-за проблем управления памятью. Этот поток упоминает проблему и предлагает решение, но является предварительным выпуском NDA и испытывает недостаток в коде. Вот длинная ветка, в которой обсуждается проблема без четкого ответа.
Вот код, который я использовал:
static NSString *CellIdentifier = @"MyCellIdentifier";
MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
cell = (MyCell *)[nib objectAtIndex:0];
}
Чтобы использовать этот код, создайте MyCell.m / .h, новый подкласс UITableViewCell
и добавьте IBOutlets
для компонентов, которые вы хотите. Затем создайте новый файл «Пустой XIB». Откройте файл Xib в IB, добавьте UITableViewCell
объект, установите для его идентификатора «MyCellIdentifier», установите для его класса значение MyCell и добавьте свои компоненты. Наконец, подключите IBOutlets
к компонентам. Обратите внимание, что мы не установили владельца файла в IB.
Другие методы рекомендуют устанавливать владельца файла и предупреждать об утечках памяти, если Xib не загружается через дополнительный фабричный класс. Я проверил вышеизложенное в разделе «Инструменты / утечки» и не обнаружил утечек памяти.
Так каков канонический способ загрузки ячеек из Xibs? Мы устанавливаем владельца файла? Нужен ли нам завод? Если да, то как выглядит код фабрики? Если есть несколько решений, давайте выясним плюсы и минусы каждого из них ...
источник
Ответы:
Вот два метода, которые автор оригинальной версии рекомендовал инженеру IB .
Смотрите фактический пост для более подробной информации. Я предпочитаю метод № 2, так как он кажется более простым.
Способ № 1:
Способ № 2:
Обновление (2014): Метод № 2 все еще действителен, но для него больше нет документации. Раньше это было в официальных документах, но теперь удалено в пользу раскадровок.
Я разместил рабочий пример на Github:
https://github.com/bentford/NibTableCellExample
редактировать для Swift 4.2
источник
Правильное решение таково:
источник
регистр
После iOS 7 этот процесс был упрощен до ( swift 3.0 ):
Dequeue
И позже, снято с очереди ( swift 3.0 ):
Разница в том, что этот новый метод не только удаляет ячейку, но и создает ее, если она не существует (это означает, что вам не нужно делать
if (cell == nil)
махинации), и ячейка готова к использованию, как в примере выше.И, конечно же, тип связанного класса ячейки - это тот, который вы определили в файле .xib для
UITableViewCell
подкласса или, альтернативно, с помощью другого метода регистра.конфигурация
В идеале ваши ячейки уже были настроены с точки зрения внешнего вида и позиционирования контента (например, надписей и представлений изображений) к тому времени, когда вы их зарегистрировали, и к
cellForRowAtIndexPath
способу, который вы просто заполняете.Все вместе
И, конечно, все это доступно в ObjC с такими же именами.
источник
[self.tableView registerNib:[UINib nibWithNibName:@"BlaBlaTableViewCell" bundle:nil] forCellReuseIdentifier:kCellIdentifier];
Взял ответ Шона Крейвера и немного его почистил.
BBCell.h:
BBCell.m:
Я делаю все мои подклассы UITableViewCell BBCell, а затем заменяю стандарт
с участием:
источник
Я использовал метод Бентфорда № 2 :
Это работает, но следите за соединениями с владельцем файла в вашем пользовательском файле UITableViewCell .xib.
Передавая
owner:self
своеloadNibNamed
заявление, вы устанавливаете вUITableViewController
качестве владельца файла вашегоUITableViewCell
.Если вы перетащите файл заголовка в IB, чтобы настроить действия и выходы, он по умолчанию установит их в качестве владельца файла.
В
loadNibNamed:owner:options
коде Apple будет пытаться установить свойства на вашUITableViewController
, так как это владелец. Но у вас нет этих свойств, определенных там, поэтому вы получаете ошибку о том, что значение ключа соответствует кодированию :Если событие инициируется вместо этого, вы получите NSInvalidArgumentException:
Простой обходной путь - указать ваши соединения Interface Builder
UITableViewCell
вместо владельца файла:источник
Я решил опубликовать, так как мне не нравится ни один из этих ответов - вещи всегда могут быть более простыми, и это, безусловно, самый лаконичный способ, который я нашел.
1. Создайте свою Xib в Интерфейсном Разработчике, как вам нравится
2. В вашем подклассе UIViewController или UITableViewController
3. В вашем MyTableViewCellSubclass
источник
Если вы используете Interface Builder для создания ячеек, убедитесь, что вы установили Идентификатор в Инспекторе. Затем проверьте, что это то же самое при вызове dequeueReusableCellWithIdentifier.
Я случайно забыл установить некоторые идентификаторы в настольном проекте, и изменение производительности было похоже на день и ночь.
источник
Загрузка UITableViewCells из XIBs экономит много кода, но обычно приводит к ужасной скорости прокрутки (на самом деле это не XIB, а чрезмерное использование UIViews, которое вызывает это).
Я предлагаю вам взглянуть на это: ссылка ссылка
источник
Вот метод класса, который я использовал для создания пользовательских ячеек из XIB:
Затем в XIB я устанавливаю имя класса и повторно использую идентификатор. После этого я могу просто вызвать этот метод в моем контроллере представления вместо
Это достаточно быстро и используется в двух моих приложениях доставки. Это более надежно, чем вызов
[nib objectAtIndex:0]
, и, по крайней мере, на мой взгляд, более надежно, чем пример Стефана Бурло, потому что вы гарантированно получите только представление из XIB, которое является правильным типом.источник
Правильное решение это
источник
Перезагрузка NIB стоит дорого. Лучше загрузить его один раз, а затем создавать объекты, когда вам нужна ячейка. Обратите внимание, что вы можете добавить UIImageViews и т. Д. К пиру, даже к нескольким ячейкам, используя этот метод (Apple «registerNIB» iOS5 допускает только один объект верхнего уровня - Ошибка 10580062 «iOS5 tableView registerNib: чрезмерно ограничительный»)
Итак, мой код ниже - вы читаете в NIB один раз (при инициализации, как я, или в viewDidload - что угодно. С тех пор вы создаете экземпляр nib в объектах, а затем выбираете тот, который вам нужен. Это намного эффективнее, чем загрузка nib снова и снова.
источник
Проверьте это - http://eppz.eu/blog/custom-uitableview-cell/ - действительно удобный способ использования крошечного класса, который заканчивается одной строкой в реализации контроллера:
источник
Правильный способ сделать это - создать реализацию подкласса UITableViewCell, заголовок и XIB. В XIB удалите все представления и просто добавьте ячейку таблицы. Установите класс как имя подкласса UITableViewCell. Для владельца файла сделайте его именем класса подкласса UITableViewController. Подключите владельца файла к ячейке, используя выход tableViewCell.
В заголовочном файле:
В файле реализации:
источник
Что я делаю для этого, объявляю
IBOutlet UITableViewCell *cell
в вашем классе контроллера. Затем вызовитеNSBundle loadNibNamed
метод класса, который передастUITableViewCell
ячейку, объявленную выше.Для xib я создам пустой xib и добавлю
UITableViewCell
объект в IB, где он может быть настроен по мере необходимости. Это представление затем подключается к ячейкеIBOutlet
в классе контроллера.Дополнения NSBundle loadNibNamed (вход в АЦП)
Статья cocoawithlove.com, из которой я получил эту концепцию (пример приложения для телефонных номеров)
источник
Создайте свой собственный настраиваемый
AbcViewCell
подкласс класса изUITableViewCell
(убедитесь, что ваше имя файла класса и имя файла пера совпадают)Создайте этот метод класса расширения.
Используй это.
let cell: AbcViewCell = UITableViewCell.fromNib()
источник
Сначала импортируйте свой пользовательский файл ячейки,
#import "CustomCell.h"
а затем измените метод делегата, как указано ниже:источник
В Swift 4.2 и Xcode 10
У меня есть три файла ячеек XIB
во ViewDidLoad зарегистрируйте свои файлы XIB следующим образом ...
Это первый подход
Второй подход - напрямую зарегистрировать файлы XIB в cellForRowAt indexPath:
Это мои функции делегата таблицы
источник
Вот мой метод для этого: загрузка пользовательских UITableViewCells из файлов XIB ... еще один метод
Идея состоит в том, чтобы создать подкласс SampleCell
UITableViewCell
соIBOutlet UIView *content
свойством и свойством для каждого настраиваемого подпредставления, которое необходимо настроить из кода. Затем создать файл SampleCell.xib. В этом nib-файле измените владельца файла на SampleCell. Добавьте контент,UIView
размер которого соответствует вашим потребностям. Добавьте и настройте все необходимые подпредставления (метка, изображения, кнопки и т. Д.). Наконец, свяжите представление содержимого и подпредставления с владельцем файла.источник
Вот универсальный подход для регистрации ячеек в
UITableView
:Объяснение:
Reusable
Протокол генерирует идентификатор ячейки из имени класса. Убедитесь, что вы следуете соглашениюcell ID == class name == nib name
.UITableViewCell
соответствуетReusable
протоколу.UITableView
Расширение абстрагирует разницу в регистрации ячеек с помощью пера или класса.Пример использования:
источник
Я не знаю, есть ли канонический путь, но вот мой метод:
И используйте этот код:
В вашем примере, используя
может сломаться, если Apple изменит порядок элементов в xib.
источник
источник
Для этого расширения требуется Xcode7 beta6
Создайте файл Xib, который содержит только 1 пользовательский UITableViewCell.
Загрузите это.
источник
источник