IOS 7/8 UITableView Cell: два UILabels с динамической высотой с автоматической компоновкой для переменной высоты строки
Таким образом, я могу настроить динамический размер высоты с помощью автоматического макета, когда у меня есть только одна метка, которая изменяет высоту в зависимости от длины строки.
Моя проблема в том, что если я добавлю еще один UILabel, который должен сделать то же самое, все не получится.
Я устанавливаю как приоритет Content Hugging, так и сопротивление сжатия 1000 для обоих == Я получаю предупреждения о двусмысленности
Если я устанавливаю Content Hugging (Вертикальный) для второго UILabel на 999 или 250, тогда он отлично работает, но только если вторая метка имеет 2 или более строк. Если вторая метка пуста или имеет только одну строку, heightForRowAtIndexPath systemLayoutSizeFittingSize: высота UILayoutFittingCompressedSize возвращает большие значения, а ячейки имеют большие пробелы.
Я также играл с Intrinsic Size: Default или Placeholder (с парой высот и ширины), но это тоже не помогает.
Какие-либо предложения о том, что можно сделать?
Ответы
Ответ 1
Наконец-то я работал. Решение было для меня явно установить предпочтительную ширину на текущую ширину кадра.
Таким образом, в основном проверка флажка Явная в ярлыке > Предпочтительная ширина в Инспекторе размеров.
ref: http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout
загрузите образец кода и посмотрите настройку раскадровки.
Ответ 2
Для меня это взяло комбинацию нескольких вещей.
- Кроме того, чтобы обеспечить правильное обжатие содержимого и сопротивление
- Мне пришлось сделать подкласс UILabel для обработки предпочтительнойMaxLayoutWidth метки
- и исправить ошибку в intrinsicContentSize, а также
Подкласс UILabel выглядит следующим образом:
@implementation LabelDynamicHeight
- (void)layoutSubviews
{
[super layoutSubviews];
self.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
- (void)setBounds:(CGRect)bounds
{
[super setBounds:bounds];
if (self.numberOfLines == 0)
{
CGFloat boundsWidth = CGRectGetWidth(bounds);
if (self.preferredMaxLayoutWidth != boundsWidth)
{
self.preferredMaxLayoutWidth = boundsWidth;
[self setNeedsUpdateConstraints];
}
}
}
- (CGSize)intrinsicContentSize
{
CGSize size = [super intrinsicContentSize];
if (self.numberOfLines == 0)
{
// There a bug where intrinsic content size may be 1 point too short
size.height += 1;
}
return size;
}
@end
Помимо этого вызова layoutIfNeeded в ячейке перед тем, как получить высоту в tableView heightForRowAtIndexPath:
, необходимо сделать ограничения, прежде чем использовать метод systemLayoutSizeFittingSize:
в contentView. Выглядит так:
- (CGFloat)tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ...;
CGFloat height = cell.frame.size.height;
if (cell.dynamicHeight)
{
// https://stackoverflow.com/a/26351692/1840269
[cell layoutIfNeeded];
height = cell.frame.size.height;
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
if (size.height > height)
height = size.height;
}
return height;
}
Литература:
Ответ 3
Для меня настройка приоритета сжатия содержимого и приоритета сжатия содержимого ниже, чтобы один из элементов работал так, как ожидалось.