iOS - перерисовывать TableViewCells с динамической высотой ячеек при вращении

Как я могу заставить свои ячейки перерисовываться после поворота устройства?

Когда я тестирую на iPhone, ориентация по умолчанию - портретная, поэтому мои динамические ячейки имеют такую ​​высоту, какой они должны быть, когда устройство находится в портретной ориентации: это означает, что когда я поворачиваюсь в альбомную ориентацию, на экране появляется много пустого места. клетка. Когда я тестирую на iPad, все наоборот. При повороте в портретную ориентацию часть текста обрезается, поскольку по умолчанию используется альбомная ориентация. У меня есть отдельные раскадровки для обоих устройств, и для обоих контроллеров представления установлено значение «Ориентация: предполагаемая».

введите описание изображения здесь(Портрет)  введите описание изображения здесь (Пейзаж)

Вот что происходит на iPhone - растягивающаяся этикетка имеет темно-красный фон, поэтому вы можете видеть фактический размер этикетки. Однако высота ячейки не пересчитывается, и, поскольку нижние метки ограничены нижней частью ячейки, они полностью находятся внизу сами по себе. Если я добавлю ограничение из метки растягивания (той, что с фоном) в нижнюю часть ячейки, все, что он сделает, это растянет метку следующим образом:

введите описание изображения здесь(Ярлык растянут)

Это говорит мне о том, что прямо сейчас я просто не могу заставить ячейку знать, что такое ориентация, и перерисовать, как только она изменится, чтобы соответствовать. Вот мой heightForRowAtIndexPath код, который вычисляет высоту ячейки:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (!self.opCell)
        {
            self.opCell = [self.container dequeueReusableCellWithIdentifier:@"OPCell"];
        }
    self.opCell.opName.text = [[self.data objectAtIndex:indexPath.row] valueForKey:@"name"];
    [self.opCell layoutIfNeeded];
    CGFloat height = [self.opCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    return height + 1;
}

Пока что, чтобы заставить его вращаться, я пробовал [self.container reloadData], где контейнер - это мой TableView с willRotateToInterfaceOrientation и didRotateToInterfaceOrientation, но безрезультатно. Я также попытался поместить его в viewDidLoad, чтобы, возможно, обнаружить и загрузить, когда представление загружается в альбомном режиме с правильной высотой, но это тоже не сработало. Для iPhone, независимо от того, что я делаю, он загружает высоту для портретного просмотра и не обновляется при повороте.

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

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

Этот учебник, похоже, дает некоторое представление об изменении высоты стола, поэтому я добавил код begin/endUpdates в мой didRotateToInterfaceOrientation, думая, что это может вызвать изменение, но это тоже не сработало.

Итак, если у кого-то есть какие-либо предложения или кто-то знает решение, я был бы очень признателен, так как этим я бью кирпичную стену!


person Eichhörnchen    schedule 07.07.2014    source источник
comment
Вы должны переместить из метода то, что не имеет ничего общего с вычислением высоты ... это было бы хорошим началом.   -  person nhgrif    schedule 08.07.2014
comment
Мне нужен весь код в моем методе heightForRowAtIndexPath. Я должен объявить ячейку, объявить заголовок, который я хочу сделать динамической высотой, а затем сказать ей, чтобы она вычисляла высоту с помощью последних двух строк. Динамические ячейки сложнее, чем нужно, и это работает.   -  person Eichhörnchen    schedule 08.07.2014
comment
Это хороший учебник, как создать динамический tableViewCells. raywenderlich.com/73602/   -  person samir    schedule 15.07.2014
comment
@samir спасибо! Я применил один более простой метод, потому что я думал, что учебник на этом сайте для динамических ячеек больше относится к iOS6 или более ранней версии. Пример кода там, кажется, делает то, что мне нужно - подумайте о добавлении этого в качестве ответа с некоторыми деталями / ключевыми моментами для награды ....   -  person Eichhörnchen    schedule 15.07.2014


Ответы (3)


Похоже, вы здесь делаете перенос слов. Итак, исходя из моего предыдущего опыта, я предлагаю вам:
1) использовать sizeWithFont или более новую версию iOS7 с соответствующим режимом разрыва строки.
2) Вы можете реализовать layoutSubview для своей "opCell", где вы можете переопределить размер кадра.
3) Рассчитайте высоту ячейки во время вращения .. убедитесь, что вы правильно установили ширину в соответствии с новым tabelView Bounds.
4) Также вы можете реализовать EstimatedHeightForRowAtIndexPath для быстрой оценки размера для операции перезагрузки таблицы.

Надеюсь это поможет !!

person Vik    schedule 14.07.2014
comment
1) В настоящее время я изменяю размер метки, просто используя счетчик строк 0 в раскадровке, и, похоже, он работает. Должен ли я использовать sizeWithFont, например, heightForRowAtIndexPath? это повлияет только на высоту этикетки? и для 2 и 3 Как мне реализовать размер ячейки в этих методах, если я делаю это там, а не heightForRowAtIndexPath? - person Eichhörnchen; 15.07.2014

Итак, я понял свою проблему. Следуя этому руководству, я обнаружил, что отсутствует.

Мне пришлось:

  1. Создайте подкласс моей метки, которая растягивалась, и укажите, что preferredMaxLayout соответствует ширине экрана.

  2. В моем heightForRowAtIndexPath мне нужно указать ячейке получить и обновить текущую ширину экрана

См. Руководство для получения более подробной информации. Надеюсь, этот вопрос и ответ помогут кому-то в будущем, потому что это было чрезвычайно хлопотно.

person Eichhörnchen    schedule 23.07.2014

Вы можете использовать тот же трюк, что и здесь. Это зовет:

[tableView beginUpdates];
[tableView endUpdates];

Без чего-либо посередине. Это вызовет пересчет высоты для представления таблицы.

person Rivera    schedule 10.07.2014
comment
Как я уже сказал, я уже пробовал это и не получаю никаких результатов. Я пробовал использовать этот метод в ViewDidLoad, viewDidLayoutSubviews, heightForRowAtIndexPath, didRotateFromInterfaceOrientation и reloadRowsAtIndexPath. Есть ли еще что-нибудь, что я должен положить? - person Eichhörnchen; 10.07.2014
comment
Я бы заселился только в didRotateFromInterfaceOrientation. Большинство других упомянутых вами методов запускаются _2 _ / _ 3_ и могут привести к возникновению цикла. - person Rivera; 11.07.2014
comment
Я пробовал это только там в одиночку, а также с некоторыми другими местами, это просто не работает для меня. - person Eichhörnchen; 15.07.2014