dequeued UITableViewCell имеет неправильный макет до прокрутки (с использованием автозапуска)

20

У меня есть собственный подкласс UITableViewCell , который имеет ограничения на автоопределение, применяемые к нему в Interface Builder. Ячейка содержит несколько видов, включая UITextField .

Соответственно, размер UITextField ограничен таким, что между ним и следующим представлением существует горизонтальное расстояние по умолчанию.

Ячейка создается следующим образом:

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

    cell.textField.text = @"Some string that is different for each cell";

    return cell;
}

Когда ячейка сначала появляется, UITextField перехватывает правильный фрейм и появляется справа от UIView . Однако, когда я прокручиваю ячейку с экрана, приостанавливаю и затем прокручиваю назад, текст усекается правильно.

Пример показан ниже (во втором редактировании).

Я попытался вызвать [cell setNeedsLayout] и [cell setNeedsDisplay] для ячейки в cellForRowAtIndexPath , а также выполнить их после задержки. Неэффективно.

Что такое прокрутка экрана, что вызывает корректность отображения ячейки, и как я могу либо ее реплицировать, либо исправить основную проблему?

EDIT:

Вызов

[self.tableView reloadData];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];

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

Однако теперь прерывает (иногда) при прокрутке (т. е. при прокрутке назад, ограничения макета теперь не применяются правильно).

Вызов [cell setNeedsLayout] в cellForRowAtIndexPath не устраняет эту проблему.

EDIT2:

Верхняя ячейка, как показано на рисунке здесь , появилась правильно (как нижняя ячейка), пока я не прокручу экран вниз. Он с тех пор исчез.

Это отражает проблему с первого редактирования - это второй рендеринг, который является проблемой (заставляет меня думать, что это может иметь какое-то отношение к повторному использованию ячейки?)

    
задан sapi 21.02.2013 в 07:01
источник
  • Вы получаете предупреждения о ограничениях в консоли? –  rdelmar 21.02.2013 в 08:20
  • Можете ли вы включить некоторые скриншоты? –  jrturton 21.02.2013 в 09:06
  • @rdelmar Я написал свою категорию Autolayout (разве мы не обсуждали это раньше?), если вам интересно: commandshift.co.uk/blog/2013/02/20/... –  jrturton 21.02.2013 в 09:08
  • Я загрузил пример изображения здесь: imgur.com/a/IKv0Z. В консоли @rdelmar нет предупреждений о ограничениях, и все они настроены через IB, поэтому они должны быть действительными. –  sapi 21.02.2013 в 11:24
  • Я не вижу ничего плохого в этих ограничениях. Я попытался дублировать вашу проблему, но мой укороченный длинный текст без прокрутки. Если вы сделаете ограничение ширины = вместо> = это поможет? Можете ли вы просто удалить его (это будет зависеть от того, что у вас есть для остальных 2 объектов справа)? –  rdelmar 21.02.2013 в 16:34

2 ответа

37

Если вы укажете свойство в подклассе UITableViewCell textLabel или defaultTextLabel , тогда IB проигнорирует указанные вами ограничения и переопределит их по умолчанию, без каких-либо предупреждений.

Это справедливо даже для ячеек, разработанных в IB с пользовательским стилем, которые не имеют видимых свойств textLabel или detailTextLabel .

Это также происходит, если добавить свойство свойства типа UIImageView в подкласс UITableViewCell и называть его imageView .

    
ответ дан sapi 22.02.2013 в 00:53
  • То же самое касается и свойства imageView. –  RickiG 28.08.2013 в 10:46
  • Этот ответ нужно продвигать в ссылке класса UITableViewCell, я просто потратил 4 часа в моей жизни. его 4 утра ... –  atreat 16.11.2013 в 10:01
  • Большое вам спасибо. Ты просто спас мне несколько часов жизни. –  Ville Laurikari 22.04.2014 в 14:38
  • Я хочу, чтобы интерфейс Builder или компилятор дал вам предупреждение о непреднамеренном переопределении этих имен свойств. –  race_carr 14.05.2014 в 20:30
  • То же самое относится к свойствам UIImageView с именем «maskView». –  Dylan Moore 22.03.2015 в 15:36
5

В соответствии с этим несколькими строками UILabel проблемы GitHub , это затяжная iOS ошибка.

Я обнаружил, что в iOS 9+ эта ситуация в основном возникает в режиме редактирования с большой непредсказуемостью.

Приведенное ниже обходное решение работает только частично: требуется дважды перерисовать UITableView и все еще не охватывает все сценарии.

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.setNeedsLayout()
    tableView.layoutIfNeeded()
    tableView.reloadData()
}

Примечания:

  • Использование UITextView - отличная альтернатива нескольким линиям UILabel без ошибок. UITextView не отображает ни одну из% других co_de%, например ошибки выравнивания или мерцающий
  • Существует также альтернативное решение SO-25947146 , которое не работает для меня, но стоит упомянуть.
  • Кажется, что происходит заметно, когда IULabel self.tableView.editing
  • Использование низких значений для true уменьшает вероятность появления
  • Демонстрация ошибки на SwiftArchitect / TableViewControllerRowHeightBug gist
ответ дан SwiftArchitect 06.02.2016 в 02:10