Почему мой 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 ответов

После всех этих попыток, когда я установил стиль ячейки табличного представления на "Субтитры" в раскадровке, субтитры показались мне Настройка ячейки раскадровки IB

Регистрация стандартного класса 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;
}
Другие вопросы по тегам