Почему мой UITableViewCell не показывает detailTextLabel в ЛЮБОМ стиле?
Этот заставляет меня вырывать волосы. Я просто пытаюсь создать таблицу со стилем UITableViewCellStyleSubtitle, с текстом и деталями. Но детали не отображаются. Обычно это происходит потому, что кто-то забыл инициализировать ячейки с правильным стилем, но в данном случае это не так. Я перепробовал все четыре стиля ячеек, и детали не отображаются ни в одном из них, хотя текстовая метка переходит вправо, когда я использую UITableViewCellStyleValue2.
Я успешно создавал таблицы много раз раньше. Единственное существенное различие, о котором я могу думать в этом случае, состоит в том, что я не использую UITableViewController. Вместо этого я встраиваю UITableView, как и любое другое представление, и подключаю свой собственный источник данных и делегат.
Я свел ключевой метод к этому:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Get the UITableViewCell (out of the recycling pool, or de novo)
NSString *reuseID = @"CELL";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseID];
if (not cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:reuseID] autorelease];
}
cell.textLabel.text = @"Foo";
cell.detailTextLabel.text = @"Bar";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.detailTextLabel.frame = CGRectMake(10, 20, 200,22); // required
cell.detailTextLabel.font = [UIFont boldSystemFontOfSize:12]; // also required
//[cell setNeedsLayout]; (makes no difference)
return cell;
}
Я могу видеть подробный текст, только если я включаю ОБА из "обязательных" строк выше (и использую любой стиль ячейки, кроме Default), и даже когда я делаю это, позиция текстовой метки полностью перекрывает позицию метки детали,
Таким образом, создается впечатление, что инициализатор создает UILabel detailTextLabel, но устанавливает его размер шрифта на ноль, а его кадр на что-то пустое или за кадром. (Я попытался проверить их в отладчике, но это не очень полезно - размер шрифта равен нулю, а рамка пуста для ОБА, textLabel и detailTextLabel, но textLabel всегда отображается нормально.)
Очевидно, я могу обойти это, если придется, вручную настраивая размеры этикеток и шрифты. Но меня очень беспокоит то, что я должен сделать это в этом случае, когда обычно вы просто устанавливаете стиль, а текст и макет выполняются автоматически. Я искал Google и переполнения стека, но не могу найти ссылки на подобную проблему. Кто-нибудь знает, что здесь происходит?
(Тестирование под iOS 6.1.)
5 ответов
После всех этих попыток, когда я установил стиль ячейки табличного представления на "Субтитры" в раскадровке, субтитры показались мне
Регистрация стандартного класса UITableViewCell не позволяет использовать стилизованные UITableViewCells, поскольку этот блок кода никогда не будет выполнен
if (not cell) {
// .... Cell will never be nil if a class/nib is registered
}
Решение: вы регистрируете перо или класс в вашем tableView? Если у вас есть строка, подобная следующей, вы должны удалить ее
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kMCControlsCellIdentifier];
и обновите свое заявление об изъятии, как следует
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kMCControlsCellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kMCControlsCellIdentifier];
}
Итак, получается, что у нас есть очень необычный процесс сборки в этом приложении, который не правильно идентифицировал SDK, против которого было собрано приложение, в инфраструктуру Cocoa.
В результате, Какао подумал, что это очень старое приложение - от дней до iOS4, до того, как был добавлен detailTextLabel. Таким образом, фреймворк пытался быть полезным, эмулируя поведение до iOS4 (скрывая detailTextLabel несколькими способами). Установка точки останова на _UIApplicationLinkedOnOrAfter и принудительное возвращение 1, позволило мне взломать эту функцию и доказать, что она была причиной. (И теперь нам просто нужно исправить наш процесс сборки, чтобы сообщить правильную версию SDK.)
Излишне говорить, что это не то, с чем столкнется большинство людей. Но я думал, что выложу ответ здесь ради потомства в любом случае.
Я надеюсь, что это поможет вам, когда-то проверить это
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = @"Foo";
cell.detailTextLabel.text = @"Bar";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.frame = CGRectMake(10, 20, 100,22);
return cell;
}
такие операции, как размер шрифта, изменение цвета фона для cell.labels, - все эти функциональные возможности, которые вы должны выполнить в следующем методе.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
cell.detailTextLabel.font = [UIFont boldSystemFontOfSize:10];
cell.textLabel.backgroundColor=[UIColor redColor];
cell.textLabel.frame = CGRectMake(10, 20, 100,22);
cell.detailTextLabel.frame = CGRectMake(10, 20, 200,22);
}
если вы изменяете эти типы свойств в cellForRowAtIndexPath этим методом, то вы потеряете эти свойства.
Проблема в том, что вы, скорее всего, зарегистрировали свою камеру, используя
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CELL"];
Имея в виду
if (not cell) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:reuseID] autorelease];
}
никогда не будет вызван, потому что ячейка никогда не будет нулевой. Поэтому ячейка всегда будет инициализирована в UITableViewCellStyleNone таблицей.
Единственный способ исправить это - зарегистрировать ячейку в раскадровке или создать подкласс UITableViewCell и переопределить
(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
метод.
Это работает для меня:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:reuseIdentifier]) {
}
return self;
}