Подтвердить что ты не робот

Ios 8 Подробный текст UITableViewCell не корректно обновляется

Изменить: tl; dr: Могу ли я заставить detailTextLabel обновлять свой размер с помощью системы автоматического макета в iOS при изменении значения?

Edit2: У меня есть частичное решение, но продолжу поиск лучшего. См. Ниже.

У кого-нибудь еще были проблемы с меткой detailText в UITableViewCell с iOS 8?

У меня есть таблица, которая содержит как текстовые, так и подробные строки. Первоначально подробный текст представляет собой пустую строку (@""). После выполнения сериала раскадровки на экране редактирования я возвращаюсь с новым значением для подробного текста и обновляю его. Я пытаюсь перезагрузить таблицу в viewWillAppear, чтобы значение было сразу же после возврата к предыдущему виду.

Когда вид таблицы снова виден, ячейка таблицы сдвинула текстовое поле вверх, чтобы освободить место для подробного текста, но не отображается подробный текст. Текст не отображается, пока я не вернусь на экран редактирования и не вернусь второй раз.

Что я сделал для устранения неполадок: Похоже, что макет автоматической компоновки для текстовой метки детали не корректно обновляется, как я думаю, и должен регистрировать размер и состав detailTextLabel кадр подтверждает это.

Я могу заставить текст обновить, запустив [table reloadData] в viewDidAppear, однако это оставляет меня с мерцающим эффектом, который мне не нравится, и выглядит непрофессиональным.

Изменить: дополнительные действия, которые я сделал: я также заставил detailTextLabel перестраивать себя, используя [cell.detailTextLabel sizeToFit]. Это заставляет его отображать, но смещается в ячейке нечетным образом. После того, как вы снова перейдете на страницу редактирования, detailTextLabel зафиксирует ее положение.

Я создал простой проект как репозиторий github, чтобы точно показать, что я имею в виду:

https://github.com/acidaris/ios8_table_issue

Основной код контроллера просмотра, который я использую, также находится ниже.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.table reloadData]; 
}


- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section {
    return 1; 
}

- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {  
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"];

    cell.textLabel.text = @"This is a test";
    cell.detailTextLabel.text = self.value;

    CGRect frame = cell.detailTextLabel.frame;
    NSLog(@"detailTextLabel x=%f y=%f width=%f height=%f",
        frame.origin.x,frame.origin.y,frame.size.width,frame.size.height);
    return cell; 
}

Ячейка прототипирована в StoryBoard, и поэтому ячейка, выбранная dequeueReusableCellWithIdentifier: всегда определяется. Кроме того, тип ячейки в раскадровке установлен на субтитры, и он отображает, если определено начальное значение.

Если бы кто-нибудь мог помочь мне понять это, я был бы невероятно благодарен.

Частичное решение

Если вы подклассифицируете UITableViewCell, вы можете изменить кадр для detailTextLabel, когда макет будет выполнен. Это то, что я сделал, и, похоже, сработал, , но на 6 плюс я получаю странную разделительную линию между textLabel и detailTextLabel. edit: (Я скорректировал это. ) Мне не нравится это решение, но пока это лучшее, что я встретил. Он не обновляется после представления представления и относительно прост. Как я сказал выше, я продолжу искать лучшее решение.

- (void)layoutSubviews {
  [super layoutSubviews]; 
  CGRect textFrame = self.textLabel.frame;
  [self.detailTextLabel sizeToFit];

  CGFloat x = textFrame.origin.x;
  CGFloat y = textFrame.origin.y + textFrame.size.height;

  CGSize detailSize = self.detailTextLabel.frame.size;
  CGRect newFrame = CGRectMake(x, y, detailSize.width, detailSize.height);

  self.detailTextLabel.frame = newFrame;
}

Я также обновил свой проект Github, чтобы отразить свое текущее решение. Edit3: Это не работает отлично, поскольку у него неправильные значения для действительно автоматических макетов, но он работает для моих целей на данный момент.

Изменить 4: я обновил функцию layoutSubviews, чтобы сделать ее более умной. Он будет иметь размер, чтобы зафиксировать содержимое в метке и поместить метку соответствующим образом в координатах x/y относительно текстовой метки.

4b9b3361

Ответ 1

С той же проблемой. Мое решение состояло в том, чтобы вызвать [cell layoutSubviews], прежде чем возвращать ячейку в конце -tableView:cellFForRowAtIndexPath. Это работает для меня, и я не счел нужным переопределять layoutSubviews в подклассе ячейки.

Ответ 2

У меня такая же проблема, когда ячейка не обновляется правильно при использовании segue в раскадровке. Пробовал

[setNeedsLayout] and [layoutIfNeeded]

в представлении и в представлении таблицы, и он НЕ работает.

[self.tableView reloadData] is in viewDidAppear, as it should.

Затем я попробовал совет от pixbug, и он сработал. Но НЕ следует использовать [layoutSubviews] напрямую. Поэтому я попробовал те, которые рекомендованы документами в ячейке вместо tableView или представления.

Пробовал

[cell setNeedsLayout] 

но это НЕ работало.

Пытались

[cell layoutIfNeeded] 

это РАБОТАЕТ для меня.

Я положил это перед возвратом ячейки.

Ответ 3

У меня была такая же проблема в раскадровке iOS 8 (без автоматической компоновки).

У меня был вид таблицы со статической ячейкой просмотра таблицы внизу. В IB я добавил некоторые пробелы в область содержимого ячейки таблицы (Стиль: "Правая деталь" ). Затем в коде (ViewDidLoad) я обновил содержимое ячейки с помощью...

self.copyrightsCell.detailTextLabel.text = @"<a string>";

Без пробелов IB ячейка была НЕВИДИМО в портретном режиме.

Но с начальными пробелами содержимое ячейки позже отображается правильно.

Надеюсь, это поможет кому-то.

Ответ 4

У меня такая же проблема. Я уверен, что данные доступны и назначаются cell.detailTextLabel.text Я заметил, что после того, как значение было назначено, нет мерцания, если значение изменяется при возврате в tableView. Поэтому мне кажется, что есть только проблема при первом присваивании значения detailTextLabel.

Ответ 5

Итак, я последовал за этим шагом и многими другими. Это привело меня к тому, что кажется правильным ответом. Надеюсь, это поможет другим, так как это сбило меня с ума, так как iOS 7/8 внес какие-то изменения.

Мой ответ заключался в том, чтобы поместить обычный код обработки в viewWillAppear и добавить этот [self.tableview layoutSubviews] вместо [self.tableView reload data]. Я думаю, что это связано с тем, что Apple делает вещи более контролируемыми в iOS 7/8. Я ударил эту идею, просмотрев некоторую информацию о работе ячеек.

Опять же, я надеюсь, что это поможет другим решить эту неприятную проблему.

Ответ 6

Я думаю, что если вам нужно перезагрузитьData, это означает, что данные таблицы не загружаются при его создании.

Вам просто нужно будет загрузить ваши данные в viewdidload (или где-нибудь еще, до того, как представление таблицы получит свои данные), где находится ваше табличное представление, и затем соответствующим образом создать ячейки.

Обычно я просто использую массив любого объекта, который я использую, а затем использую [array objectAtIndex:indexpath.row], о котором вы, вероятно, знаете.

Кроме того, в предыдущем абзаце есть незавершенное предложение, которое выглядит важным.

Ответ 7

Подтверждение проблемы с помощью Xcode 6.3.2 (6D2105) OS X Yosemite 10.10.3 Я удостоверился, что правильное значение было назначено, но в первый раз нет шоу,  второй раз шоу. cell.layoutSubviews() казался логичным для меня, так как казалось, что в представлении не было обновления, а добавление layoutSubviews() делало трюк.

Ответ 8

У меня была аналогичная проблема со статическим UITableView. Я меняю текст ярлыка, и он не обновляется на экране, если я не щелкнул по ячейке или не сделал ничего, чтобы принудительно обновить его представления. Мое обходное решение состояло в том, чтобы вызвать после обновления текста:

tableView.reloadData()

P.S Это не имеет никакого смысла; потому что это статический вид таблицы, и я не знаю, почему это сработало, но это было!