Я могу создавать собственные UITableViewCells и загружать их, используя технику, описанную в ветке http://forums.macrumors.com/showthread.php?t=545061 . Однако использование этого метода больше не позволяет вам инициализировать ячейку с помощью reuseIdentifier, что означает, что вам нужно создавать совершенно новые экземпляры каждой ячейки при каждом вызове. Кто-нибудь придумал хороший способ кэшировать определенные типы ячеек для повторного использования, но при этом иметь возможность создавать их в Interface Builder?
ios
iphone
uitableview
cocoa-touch
interface-builder
Грег Мартин
источник
источник
return NSStringFromClass([self class]);
Фактически, поскольку вы создаете ячейку в Interface Builder, просто установите там идентификатор повторного использования:
Или, если вы используете Xcode 4, проверьте вкладку инспектора атрибутов:
(Изменить: после того, как ваш XIB сгенерирован XCode, он содержит пустой UIView, но нам нужен UITableViewCell; поэтому вам нужно вручную удалить UIView и вставить ячейку представления таблицы. Конечно, IB не будет отображать какие-либо параметры UITableViewCell для UIView.)
источник
Теперь в iOS 5 для этого есть подходящий метод UITableView:
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier
источник
Я не могу вспомнить, где я изначально нашел этот код, но до сих пор он отлично работал у меня.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"CustomTableCell"; static NSString *CellNib = @"CustomTableCellView"; UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil]; cell = (UITableViewCell *)[nib objectAtIndex:0]; } // perform additional custom work... return cell; }
Пример настройки Interface Builder ...
источник
Посмотрите, какой ответ я дал на этот вопрос:
Можно ли разработать подклассы NSCell в Интерфейсном Разработчике?
В IB можно не только спроектировать UITableViewCell, но и желательно, потому что в противном случае вся ручная разводка и размещение нескольких элементов очень утомительна. Исполнение в порядке, если вы стараетесь сделать все элементы непрозрачными, когда это возможно. ReuseID устанавливается в IB для свойств UITableViewCell, затем вы используете соответствующий идентификатор повторного использования в коде при попытке удаления из очереди.
Я также слышал от некоторых докладчиков на WWDC в прошлом году, что вы не должны создавать ячейки табличного представления в IB, но это полная чушь.
источник
Начиная с iOS около 4.0, в документации iOS есть специальные инструкции, которые делают эту работу сверхбыстрой:
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7
Прокрутите вниз до того места, где говорится о создании подкласса UITableViewCell.
источник
Вот еще вариант:
NSString * cellId = @"reuseCell"; //... NSArray * nibObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomTableCell" owner:nil options:nil]; for (id obj in nibObjects) { if ([obj isKindOfClass:[CustomTableCell class]]) { cell = obj; [cell setValue:cellId forKey:@"reuseIdentifier"]; break; } }
источник
UITableViewCell
создания подкласса для вашего пользовательского класса , чтобы установить уникальное значение дляreuseIdentifer
. Я думаю, это то, что на самом деле искала оригинальная операция.Я создаю свои настраиваемые ячейки представления аналогичным образом, за исключением того, что подключаю ячейку через IBOutlet.
[nib objectAt...]
Подход чувствителен к изменениям в позиции элементов в массиве.UIViewController
Подход хорош - просто попытался его, и он работает достаточно хорошо.НО...
Во всех случаях
initWithStyle
конструктор НЕ вызывается, поэтому инициализация по умолчанию не выполняется.Я читал в разных местах об использовании
initWithCoder
илиawakeFromNib
, но не имел убедительных доказательств того, что любой из них является правильным.Помимо явного вызова некоторого метода инициализации в
cellForRowAtIndexPath
методе, я еще не нашел на это ответа.источник
Некоторое время назад я нашел отличное сообщение в блоге по этой теме на blog.atebits.com , и с тех пор начал использовать класс Loren Brichter ABTableViewCell для выполнения всех моих UITableViewCells.
В итоге вы получаете простой контейнер UIView для размещения всех ваших виджетов, а прокрутка выполняется молниеносно.
Надеюсь, это будет полезно.
источник
Этот метод также работает и не требует фанкового ivar в вашем контроллере представления для управления памятью. Здесь ячейка настраиваемого табличного представления находится в xib с именем «CustomCell.xib».
static NSData *sLoadedCustomCell = nil; cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"]; if (cell == nil) { if (sLoadedCustomCell == nil) { // Load the custom table cell xib // and extract a reference to the cell object returned // and cache it in a static to avoid reloading the nib again. for (id loadedObject in [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil]) { if ([loadedObject isKindOfClass:[UITableViewCell class]]) { sLoadedCustomCell = [[NSKeyedArchiver archivedDataWithRootObject: loadedObject] retain]; break; } } cell = (UITableViewCell *)[NSKeyedUnarchiver unarchiveObjectWithData: sLoadedCustomCell]; }
источник
У меня сработал метод Луи. Это код, который я использую для создания UITableViewCell из пера:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"]; if (cell == nil) { UIViewController *c = [[UIViewController alloc] initWithNibName:@"CustomCell" bundle:nil]; cell = (PostCell *)c.view; [c release]; } return cell; }
источник
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *simpleTableIdentifier = @"CustomCell"; CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier]; if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil]; cell = [nib objectAtIndex:0]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } return cell; }
источник
Решение gustavogb у меня не работает, я пробовал:
ChainesController *c = [[ChainesController alloc] initWithNibName:@"ChainesController" bundle:nil]; [[NSBundle mainBundle] loadNibNamed:@"ChaineArticleCell" owner:c options:nil]; cell = [c.blogTableViewCell retain]; [c release];
Вроде работает. BlogTableViewCell - это IBOutlet для ячейки, а ChainesController - владелец файла.
источник
Из документов UITableView относительно
dequeueWithReuseIdentifier
: «Строка, идентифицирующая объект ячейки, который будет использоваться повторно. По умолчанию идентификатором повторно используемой ячейки является имя ее класса, но вы можете изменить его на любое произвольное значение».Самостоятельное переопределение -reuseIdentifer рискованно. Что произойдет, если у вас есть два подкласса подкласса ячейки, и вы используете оба из них в одном табличном представлении? Если они отправят вызов идентификатора повторного использования на super, вы удалите из очереди ячейку неправильного типа .............. Я думаю, вам нужно переопределить метод reuseIdentifier, но он вернет замещенный идентификатор строка. Или, если он не был указан, вернуть класс в виде строки.
источник
Как бы то ни было, я спросил об этом инженера по iPhone на одном из iPhone Tech Talks. Его ответ был: «Да, можно использовать IB для создания ячеек. Но не делайте этого. Пожалуйста, не надо».
источник
Я следовал инструкциям Apple, по ссылке Бена Мошера (спасибо!), Но обнаружил, что Apple упустила важный момент. Объект, который они создают в IB, - это просто UITableViewCell, как и переменная, которую они загружают из него. Но если вы на самом деле настроите его как настраиваемый подкласс UITableViewCell и напишете файлы кода для подкласса, вы можете написать объявления IBOutlet и методы IBAction в коде и связать их со своими настраиваемыми элементами в IB. Тогда нет необходимости использовать теги просмотра для доступа к этим элементам, и вы можете создать любую сумасшедшую ячейку, какую захотите. Это рай какао Touch.
источник