У меня UITableView
работает под iOS 8, и я использую автоматическую высоту ячеек от ограничений в раскадровке.
Одна из моих ячеек содержит одну ячейку, UITextView
и мне нужно, чтобы она сжималась и расширялась на основе пользовательского ввода - нажмите, чтобы уменьшить / развернуть текст.
Я делаю это, добавляя ограничение времени выполнения к текстовому представлению и меняя константу ограничения в ответ на пользовательские события:
-(void)collapse:(BOOL)collapse; {
_collapsed = collapse;
if(collapse)
[_collapsedtextHeightConstraint setConstant: kCollapsedHeight]; // 70.0
else
[_collapsedtextHeightConstraint setConstant: [self idealCellHeightToShowFullText]];
[self setNeedsUpdateConstraints];
}
Всякий раз, когда я делаю это, я оборачиваю это в tableView
обновления и вызываю [tableView setNeedsUpdateConstraints]
:
[tableView beginUpdates];
[_briefCell collapse:!_showFullBriefText];
[tableView setNeedsUpdateConstraints];
// I have also tried
// [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
// with exactly the same results.
[tableView endUpdates];
Когда я делаю это, моя ячейка расширяется (и оживляет во время этого), но я получаю предупреждение об ограничениях:
2014-07-31 13:29:51.792 OneFlatEarth[5505:730175] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>",
"<NSLayoutConstraint:0x7f94dced2260 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...']-(15)-| (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",
"<NSLayoutConstraint:0x7f94dced2350 V:|-(6)-[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'] (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",
"<NSLayoutConstraint:0x7f94dced6480 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7f94de5773a0(91)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>
388 - это моя расчетная высота, остальные ограничения для UITextView
меня - из Xcode / IB.
Последнее беспокоит меня - я предполагаю, что UIView-Encapsulated-Layout-Height
это вычисленная высота ячейки, когда она впервые отображается - (я установил мою UITextView
высоту равной> = 70.0), однако не похоже, что это производное ограничение отменяет обновлен пользователь cnstraint.
Хуже того, хотя код компоновки говорит, что он пытается нарушить мое ограничение по высоте, он этого не делает - он пересчитывает высоту ячейки, и все отрисовывается так, как мне бы хотелось.
Итак, что это NSLayoutConstraint
UIView-Encapsulated-Layout-Height
(я предполагаю, что это расчетная высота для автоматического определения размера ячеек) и как мне заставить его пересчитывать чисто?
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
. Я думаю, что изначально установка маски авторазмера останавливает добавление последнего ограничения. Я нашел это решение здесь: github.com/wordpress-mobile/WordPress-iOS/commit/…<rect key="frame" x="0.0" y="0.0" width="600" height="110"/>
в ее определении, что заставило меня поверить, что это ошибка IB. , По крайней мере, мой был в любом случае.Ответы:
Попробуйте снизить приоритет вашего
_collapsedtextHeightConstraint
до 999. Таким образом,UIView-Encapsulated-Layout-Height
ограничение системы всегда имеет приоритет.Это основано на том, что вы вернетесь
-tableView:heightForRowAtIndexPath:
. Убедитесь, что вы вернули правильное значение, и ваши собственные ограничения и сгенерированные должны быть одинаковыми. Более низкий приоритет для вашего собственного ограничения необходим только временно, чтобы предотвратить конфликты, пока анимация свертывания / развертывания находится в полете.источник
UIView-Encapsulated-Layout-Height
Ограничение добавляет UITableView после того , как высота определяется. Я рассчитываю высоту на основеsystemLayoutSizeFittingSize
контента. ЗдесьUIView-Encapsulated-Layout-Height
не имеет значения. Затем tableView явно устанавливает contentSize в значение, возвращаемоеheightForRowAtIndexPath:
. В этом случае правильно уменьшить приоритет наших пользовательских ограничений, потому что ограничение tableView должно иметь приоритет после вычисления rowHeights.UIView-Encapsulated-Layout-Height
это неправильно, если я не понизил приоритет ...UIView-Encapsulated-Layout-Width
в моем случае просто неправильно, но кажется, что оно предпочтительнее моих явных ограничений во время выполнения.У меня похожий сценарий: табличное представление с одной ячейкой строки, в которой есть несколько строк объектов UILabel. Я использую iOS 8 и autolayout.
Когда я повернулся, я получил неправильную систему, рассчитанную высоту строки (43,5 намного меньше, чем фактическая высота). Это выглядит как:
Это не просто предупреждение. Расположение моей ячейки табличного представления ужасно - весь текст перекрывается одной текстовой строкой.
Меня удивляет, что следующая строка «волшебным образом» решает мою проблему (autolayout ничего не жалует, и я получаю то, что ожидаю на экране):
с или без этой строки:
источник
estimatedRowHeight
чащеcellForRowAtIndexPath
будет вызываться изначально. высота представления таблицы, поделенная на расчетное значение RowHeight, если быть точным. На 12-дюймовом iPad Pro это может быть число в тысячах, что приведет к перебоям в источнике данных и может привести к значительной задержке.Мне удалось убрать предупреждение, указав приоритет одного из значений в ограничении, которое в предупреждающих сообщениях указано, что оно должно было выйти из строя (ниже
"Will attempt to recover by breaking constraint"
). Похоже, что пока я устанавливаю приоритет на что-то большее49
, предупреждение исчезает.Для меня это означало изменение моего ограничения, в предупреждении говорилось, что оно попыталось сломаться:
@"V:|[contentLabel]-[quoteeLabel]|"
чтобы:
@"V:|-0@500-[contentLabel]-[quoteeLabel]|"
Фактически, я могу добавить приоритет любому элементу этого ограничения, и оно будет работать. Кажется, не имеет значения, какой именно. Мои клетки в конечном итоге нужной высоты, и предупреждение не отображается. Роджер, для вашего примера, попробуйте добавить
@500
сразу после388
ограничения значения высоты (например388@500
).Я не совсем уверен, почему это работает, но я провел небольшое расследование. В перечислении NSLayoutPriority кажется, что
NSLayoutPriorityFittingSizeCompression
уровень приоритета равен50
. Документация для этого уровня приоритета гласит:Документация для ссылочного
fittingSize
сообщения гласит:Я не копался в этом, но, похоже, имеет смысл, что это как-то связано с проблемой.
источник
В 99,9% случаев при использовании пользовательских ячеек или заголовков все конфликты
UITableViews
возникают при первой загрузке таблицы. После загрузки вы больше не увидите конфликт.Это происходит потому, что большинство разработчиков обычно используют фиксированную высоту или привязку какого-либо рода для размещения элемента в ячейке / заголовке. Конфликт возникает потому, что при
UITableView
первой загрузке / выкладке он устанавливает высоту своих ячеек равной 0. Это, очевидно, противоречит вашим собственным ограничениям. Чтобы решить эту проблему, просто установите любые фиксированные ограничения высоты на более низкий приоритет (.defaultHigh
). Внимательно прочитайте консольное сообщение и посмотрите, какое ограничение система макета решила нарушить. Обычно это тот, который нуждается в изменении приоритета. Вы можете изменить приоритет следующим образом:источник
Я был в состоянии устранить эту ошибку, удалив поддельный ,
cell.layoutIfNeeded()
что у меня вtableView
«scellForRowAt
методе.источник
Вместо того, чтобы информировать табличное представление об обновлении его ограничений, попробуйте перезагрузить ячейку:
UIView-Encapsulated-Layout-Height
Вероятно, это высота таблицы, рассчитанная для ячейки во время начальной загрузки на основе ограничений ячейки в то время.источник
Другая возможность:
Если вы используете автоматический макет для вычисления высоты ячейки (высота contentView, большую часть времени, как показано ниже), и если у вас есть разделитель uitableview, вам нужно добавить высоту разделителя, чтобы вернуться к высоте ячейки. Как только вы получите правильную высоту, у вас не будет этого предупреждения об автоматическом размещении.
источник
UITableViewAutomaticDimension
вheightForRowAtIndexPath
I вернуться[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] + 0.1
[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 0.1
Как упомянул Джесси в комментарии вопроса, это работает для меня:
К вашему сведению, эта проблема не возникает в iOS 10.
источник
У меня была эта ошибка при использовании UITableViewAutomaticDimension и изменении ограничения высоты для представления внутри ячейки.
Я наконец понял, что это связано с тем, что значение константы ограничения не округляется до ближайшего целого числа.
источник
Изменение размера текстового представления в соответствии с его содержимым и обновление константы ограничения высоты в соответствии с результирующей высотой позволило
UIView-Encapsulated-Layout-Height
устранить конфликт ограничений, например:источник
Потратив несколько часов, почесывая голову с этой ошибкой, я наконец нашел решение, которое сработало для меня. Моя главная проблема заключалась в том, что у меня было зарегистрировано несколько перьев для разных типов ячеек, но одному типу ячеек было разрешено иметь разные размеры (не все экземпляры этой ячейки будут одинакового размера). поэтому проблема возникла, когда табличное представление пыталось удалить из очереди ячейку этого типа, и оказалось, что она имеет другую высоту. Я решил это, установив
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; self.frame = CGRectMake(0, 0, self.frame.size.width, {correct height});
всякий раз, когда ячейка имела свои данные для расчета ее размера. Я полагаю, что это может быть в
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
что-то вроде
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; cell.frame = CGRectMake(0, 0, self.frame.size.width, {correct height});
Надеюсь это поможет!
источник
TableView получает высоту для ячейки в indexPath от делегата. затем получить ячейку из
cellForRowAtIndexPath
:если cell.contentView.height: 0 // <-> (UIView-Encapsulated-Layout-Height: 0 @ 1000) top (10 @ 1000) конфликтует с (UIView-Encapsulated-Layout-Height: 0 @ 1000),
потому что их приоритеты равны 1000. Нам нужно установить верхний приоритет в соответствии
UIView-Encapsulated-Layout-Height
с приоритетом.источник
Я получаю сообщение, подобное этому:
Я использую кастом
UITableViewCell
сUITableViewAutomaticDimension
высотой. И я также реализовалestimatedHeightForRowAtIndex:
метод.Ограничение, которое доставляло мне проблемы, выглядело примерно так
Изменение ограничения на это решит проблему, но, как и в другом ответе, я почувствовал, что это не правильно, так как это снижает приоритет ограничения, которое я хочу требовать:
Однако, что я заметил, так это то, что если я на самом деле просто удаляю приоритет, это тоже работает, и я не получаю журналы нарушения ограничения:
Это немного загадка в том, что разница между
|-6-[title]-6-|
и|-[title-|
. Но указание размера не является проблемой для меня и избавляет от логов, и мне не нужно снижать приоритет моих необходимых ограничений.источник
Установите это
view.translatesAutoresizingMaskIntoConstraints = NO;
должно решить эту проблему.источник
У меня была похожая проблема с ячейкой представления коллекции.
Я решил это, понизив приоритет конечного ограничения, связанного с нижней частью ячейки (последней в цепочке сверху вниз в представлении - это, в конечном счете, определяет его высоту) до 999.
Высота камеры была правильной, и предупреждения исчезли.
источник