Ошибка в макете UITableView после изменения ориентации

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

  • Поверните приложение в ландшафтном режиме, чтобы теперь было просмотрено в виде таблицы.
  • Добавить элемент в таблицу просмотра 1 ниже
  • Вернитесь назад в положение "Портрет", теперь таблица будет плавать на горизонтальной панораме (как если бы размер содержимого для просмотра прокрутки был ландшафтным), см. [2]

1 Код для добавления

- (IBAction)onAdd:(id)sender {
    count ++;
    [self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:count-1 inSection:0]] withRowAnimation:UITableViewRowAnimationBottom];
}

[2] Плавающий вид таблицы

enter image description here

Любые идеи о том, как обойти эту проблему? Кроме того, как я могу узнать, является ли это известной проблемой или что-то, что я должен сообщить Apple?

Ответ 1

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

То, что происходит в вашем случае, так же, как вы подозревали, - просмотр содержимого просмотра прокрутки остается на ширине ландшафта, даже если сам вид изменился до портрета, так что вы внезапно получите возможность горизонтального перетаскивания.

К счастью, есть довольно простые обходные пути. Я экспериментировал с различными комбинациями setNeedsLayout или setNeedsUpdateConstraints без успеха, но вы можете реализовать одно из этих двух решений:

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}

Или,

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    CGSize contentSize = self.tableView.contentSize;
    contentSize.width = self.tableView.bounds.size.width;
    self.tableView.contentSize = contentSize;
}

Ответ 2

Я обнаружил, что ответы выше работают большую часть времени, но не все время. Наиболее надежным решением является подкласс UITableView и настройка contentSize в layoutSubviews:

- (void)layoutSubviews
{
    [super layoutSubviews];

    CGSize contentSize = self.contentSize;
    contentSize.width  = self.bounds.size.width;
    self.contentSize   = contentSize;
}