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

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

У меня есть пользовательский подкласс 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:

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

override func viewDidLoad() {
    super.viewDidLoad()

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

Примечания:

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