Настройка стиля UITableViewCell при использовании iOS 6 UITableView dequeueReusableCellWithIdentifier: forIndexPath:

Я пытаюсь определить, как установить UITableViewCellStyle при использовании новых методов в iOS 6 для UITableView .

Раньше при создании UITableViewCell я бы изменил перечисление UITableViewCellStyle для создания различных типов ячеек по умолчанию при вызове initWithStyle: но из того, что я могу собрать, это уже не так.

Документация Apple для UITableView гласит:

Возвращаемое значение : объект UITableViewCell с соответствующим идентификатором повторного использования. Этот метод всегда возвращает действительную ячейку.

Обсуждение . По соображениям производительности источник данных табличного представления обычно должен повторно использовать объекты UITableViewCell, когда он назначает ячейки строкам в методе tableView: cellForRowAtIndexPath:. В представлении таблицы поддерживается очередь или список объектов UITableViewCell, которые источник данных отмечен для повторного использования. Вызовите этот метод из объекта источника данных, когда его попросят предоставить новую ячейку для представления таблицы. Этот метод деактивирует существующую ячейку, если она доступна, или создает новую, основанную на ранее сохраненном файле classа или файла nib.

Важно. Перед вызовом этого метода необходимо зарегистрировать файл classа или nib, используя метод registerNib: forCellReuseIdentifier: или registerClass: forCellReuseIdentifier:.

Если вы зарегистрировали class для указанного идентификатора и должна быть создана новая ячейка, этот метод инициализирует ячейку, вызывая ее метод initWithStyle: reuseIdentifier :. Для ячеек, основанных на nib, этот метод загружает объект ячейки из предоставленного файла nib. Если существующая ячейка была доступна для повторного использования, этот метод вызывает метод prepareForReuse ячейки.

Вот как выглядит моя новая cellForRowAtIndexPath после внедрения новых методов:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"cell_identifier"; [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellIdentifier]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; return cell; } 

Код, который я до сих пор работает нормально, но всегда возвращает стиль по умолчанию. Как я могу изменить это, чтобы я мог создавать ячейки с другими стилями, такими как UITableViewCellStyleDefault , UITableViewCellStyleValue1 , UITableViewCellStyleValue2 и UITableViewCellStyleSubtitle ?

Я не хочу подclassа UITableViewCell , я просто хочу изменить тип по умолчанию, как я мог бы сделать до iOS 6. Кажется странным, что Apple предоставит расширенные методы, но с минимальной документацией для поддержки их реализации.

Кто-нибудь справился с этим или столкнулся с подобной проблемой? Я изо всех сил пытаюсь найти любую разумную информацию.

Я знаю, вы сказали, что не хотите создавать подclass, но он выглядит неизбежным. На основе кода сборки во время тестирования в симуляторе iOS 6.0 UITableView создает новые экземпляры UITableViewCell (или его подclassов), выполняя

 [[ alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:] 

Другими словами, стиль, отправленный ( UITableViewCellStyleDefault ), выглядит жестко. Чтобы обойти это, вам нужно создать подclass, который переопределяет инициализатор по умолчанию initWithStyle:reuseIdentifier: и передает стиль, который вы хотите использовать:

 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { // ignore the style argument, use our own to override self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]; if (self) { // If you need any further customization } return self; } 

Кроме того, может быть лучше отправить registerClass:forCellReuseIdentifier: in viewDidLoad , вместо того, чтобы делать это каждый раз, когда запрашивается ячейка:

 - (void)viewDidLoad { [super viewDidLoad]; [self.tableView registerClass: forCellReuseIdentifier:]; } 

dequeueReusableCellWithIdentifier не устарел, поэтому вам не требуется использовать новый dequeueReusableCellWithIdentifier:forIndexPath:

Используйте новый способ вместе с соответствующим методом register (в viewDidLoad), если вы используете собственный class ячеек, но используете старый способ, если хотите использовать одну из перечислений UITableViewCellStyle.

Вы можете избежать постороннего подclassа с помощью построителя интерфейса раскадровки:

  1. В представлении «Раскадровка» выберите ячейку прототипа ячейки таблицы (в виде таблицы)
  2. В представлении «Утилиты» в инспекторе «Атрибуты» измените значение «Стиль»
  3. (Необязательно) Изменение других значений, таких как Выбор и Аксессуар

Новый iOS 6.0 dequeueReusableCellWithIdentifier:forIndexPath: использует эти значения при распределении новых ячеек и их возвращении. (Протестировано на компиляции iOS 6.0 с использованием Xcode 4.5.2)

Другой альтернативой, которая сохраняет один файл, является создание Nib и использование registerNib:forCellReuseIdentifier: вместо этого.

Создание Nib очень просто: создайте новый .xib-файл в Interface Builder. Удалить представление по умолчанию. Добавить объект Cell View Table. С помощью Attributes Inspector измените стиль для ячейки. (Здесь у вас также есть возможность настроить камеру дальше, настроив другие атрибуты.)

Затем в вашем представлении таблицы viewDidLoad метода controllerа вызывается что-то вроде:

 [self.tableView registerNib:[UINib nibWithNibName:@"StyleSubtitleTableCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"Cell"]; 

Ответ Болота правильный. Простой и вам не нужно создавать XIB-файл.

Я просто хотел обновить его ответ для тех, кто это делает, используя Swift вместо Objective-C:

 override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: .value1, reuseIdentifier: reuseIdentifier) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } 

Моим решением для этого является вызов initWithStyle: reuseIdentifier: после того, как я его получил, используя [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath] . В конце концов, init – это еще один селектор, и компилятор не делает никаких ограничений на вызов его на уже инициализированный объект. Однако он будет жаловаться на то, что не будет использовать результат вызова init, поэтому я:

 UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath]; cell = [cell initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellId"]; 

Я предполагаю, что это не сработает в Swift …

  • Как настроить разделитель таблицы в iPhone
  • Как узнать, когда UITableView сделал прокрутку вниз в iPhone
  • Как узнать, когда UITableView завершил ReloadData?
  • Вид сетки в iPhone SDK
  • Изменение поведения прокрутки по умолчанию в заголовке раздела UITableView
  • 2 различных типа пользовательских UITableViewCells в UITableView
  • Ячейка UITableView с фоновым изображением
  • Как предоставить пространство между двумя ячейками в виде таблицы?
  • iPhone: UITableView CellAccessory Checkmark
  • Несколько UITableViews на одном UIView
  • Как прокрутить UITableView в определенную позицию
  • Давайте будем гением компьютера.