Обнаружен случай, когда ограничения неоднозначно предполагают нулевую высоту


120

После обновления до Xcode 6.1 beta 2, когда я запускаю свое приложение, содержащее ячейки tableview, помощник по отладке говорит:

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

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

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

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


2
Я получаю такую ​​же ошибку для ячейки представления коллекции. Что я для этого делаю. Какие-либо предложения.
python

Возможно, вам стоит проверить, добавили ли вы уже xib-файл в целевой stackoverflow.com/a/26870331/1418457
onmyway133


Это случилось со мной на iOS 8.1, но больше не на iOS 8.4. Если вы указали высоту, я думаю, это просто ошибка Xcode.
samwize

Ответы:


126

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

  • Чтобы установить высоту ячейки по умолчанию в viewDidLoad

    self.tableView.rowHeight = 44;
  • Перейдите в раскадровку и измените высоту строки в табличном представлении на значение, отличное от 44.

  • Для реализации метода делегата tableview heightForRowAtIndexPath

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return 44;
    }
    

Weird.


Я также пробовал использовать ваш метод, но мне нужно добавить @property для rowHeight, но я не знаю, какой тип объекта использовать
Дэвид Э

Возможно, я не получил вашу заметку, но rowHeight является свойством UITableView. Просто подключите свой стол к какой-нибудь розетке и все.
Виктор Кучера

4
Это связано с тем, что если вы сохраните значение 44pt в IB, он сочтет, что вы хотите использовать ячейки с автоматическим изменением размера. stackoverflow.com/questions/25888126/… (но, да, это действительно странное поведение)
Гийом Альгис

Очевидно, у меня было два метода viewDidLoad, и я вставил self.tableView.rowHeight = 44;не тот. Ошибка ушла! спасибо
David E

Спасибо Гийому Альгису за то, что он разъяснил это более четко. Хотя это все еще очень жутко.
Виктор Кучера

216

Вы сталкиваетесь с побочным эффектом новой фантастической функции в iOS8 Tableviews: Automatic Row Heights.

В iOS 7 у вас либо были строки фиксированного размера (заданные с помощью tableView.rowHeight), либо вы написали код для вычисления высоты ваших ячеек и вернули бы его в tableView:heightForRowAtIndexPath. Написание кода для вычисления высоты ячейки могло бы быть довольно сложным, если бы у вас было множество представлений в вашей ячейке и у вас были разные высоты, которые нужно учитывать при разных размерах шрифта. Добавьте динамический тип, и процесс оказался занозой в заднице.

В iOS 8 вы по-прежнему можете делать то же самое, но теперь iOS может определять высоту строк при условии, что вы настроили содержимое ячейки с помощью Auto Layout. Это огромное преимущество для разработчиков, поскольку при изменении размера динамического шрифта или изменении размера текста пользователем с помощью настроек специальных возможностей пользовательский интерфейс может адаптироваться к новому размеру. Это также означает, что если у вас есть UILabel, который может иметь несколько строк текста, ваша ячейка теперь может увеличиваться, чтобы вместить их, когда это необходимо ячейкам, и сжиматься, когда это не так, поэтому нет ненужных пробелов.

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

Чтобы использовать динамическую высоту ячейки, которая, наряду с методами, уже упомянутыми в других плакатах, также избавит от этого сообщения, вам необходимо убедиться, что ваша ячейка имеет достаточные ограничения для привязки элементов пользовательского интерфейса к верхней и нижней части ячейки. Если вы раньше использовали Auto Layout, вы, вероятно, привыкли устанавливать ограничения Top + Leading, но для динамической высоты строки также требуются ограничения снизу.

Этап макета работает так, что происходит непосредственно перед отображением ячейки на экране точно в срок:

  1. Рассчитываются размеры содержимого с внутренними размерами. Это включает UILabels и UIImageViews, где их размеры основаны на тексте или UIImages, которые они содержат, соответственно. Оба этих представления будут считать свою ширину известной (потому что вы установили ограничения для задних / передних кромок, или вы установили явную ширину, или вы использовали горизонтальные ограничения, которые в конечном итоге показывают ширину из стороны в сторону). Допустим, у метки есть абзац текста («количество строк» ​​установлено на 0, поэтому он будет автоматически переноситься), он может быть только 310 точек в поперечнике, поэтому он определен как высотой 120 пунктов при текущем размере шрифта.

  2. Пользовательский интерфейс размещен в соответствии с вашими ограничениями позиционирования. В нижней части метки есть ограничение, которое соединяется с нижним полем ячейки. Поскольку метка выросла до 120 точек в высоту, и поскольку она привязана к нижней части ячейки ограничением, она должна подтолкнуть ячейку «вниз» (увеличивая высоту ячейки), чтобы удовлетворить ограничение, которое гласит «нижняя часть метка всегда находится на стандартном расстоянии от низа ячейки.

Сообщение об ошибке, о котором вы сообщили, возникает, если это нижнее ограничение отсутствует, и в этом случае нет ничего, что могло бы "отодвинуть" нижнюю часть ячейки от верхней части ячейки, что является сообщением двусмысленности: нечего толкать нижнюю часть из вверху ячейка разрушается. Но Auto Layout тоже обнаруживает это и возвращается к использованию стандартной высоты строки.

Что бы это ни стоило, и в основном для получения округленного ответа, если вы действительно реализуете динамическую высоту строк на основе автоматического макета iOS 8, вам следует реализовать tableView:estimatedHeightForRowAtIndexPath:. Этот метод оценки может использовать приблизительные значения для ваших ячеек, и он будет вызываться при первоначальной загрузке табличного представления. Это помогает UIKit рисовать такие вещи, как полоса прокрутки, которую нельзя нарисовать, если табличное представление не знает, сколько контента оно может прокручивать, но не требует абсолютно точных размеров, поскольку это просто полоса прокрутки. Это позволяет отложить вычисление фактической высоты строки до момента, когда ячейка понадобится, что требует меньших вычислительных затрат и позволяет быстрее представить ваш UITableView.


3
Это отличное объяснение основной причины этого предупреждения. Спасибо, Вудстер, за уделенное время!
Golden Thumb

4
Как и то, что сказал Вудстер, я пропустил нижнюю часть ограничений. При добавлении моя проблема была решена.
Golden Thumb

Попробовав почти 20 вещей, это единственное, что сработало!
Хулио Родригес

Этот человек справился! Он заслуживает и поддерживает, и это должен быть принятый ответ. +1
Caribbean

1
См. Этот ответ stackoverflow.com/a/29565073/4080860 , чтобы выяснить, в какой ячейке отсутствуют ограничения.
hhanesand

11

У меня возникла эта проблема после создания настраиваемого UITableViewCellи добавления моих вложенных представлений в ячейку вместо ее contentView.


10

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

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


Лучшее решение для меня, потому что я использую раскадровку вместо строк кода.
zyc

6

Это проблема автоматического раскладки. Убедитесь, что ваши subviews имеют все ограничения. Для меня нижнее ограничение отсутствовало для заголовка в ячейке. Когда я добавил это, предупреждение исчезло, и все появилось отлично.


Не знаю, почему это было отклонено, поскольку это совершенно хороший ответ. См. Здесь, чтобы узнать, в какой ячейке возникают проблемы с размещением stackoverflow.com/a/29565073/4080860
hhanesand

5

Просто включите саморазмерные ячейки представления таблицы

   tableView.estimatedRowHeight = 85.0
   tableView.rowHeight = UITableViewAutomaticDimension

и убедитесь, что вы добавили ограничения со всех сторон UITableViewCellас-

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


Собственно, предупреждение исчезло, когда я отключил саморазмеры ячеек tableview.
проверено turing

@turingtested вы должны включить саморазмерную ячейку tableview для поддержки на различных устройствах.
Джек

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

FYI UITableViewAutomaticDimensionбыл переименован вUITableView.automaticDimension
atineoSE

5

Если вы используете статическую или динамическую ячейку, просто добавьте высоту строки в представление таблицы в таблице инспектора и снимите флажок автоматически справа от высоты строки, и вы перестанете получать это предупреждение.введите описание изображения здесь


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

4

Я получил это предупреждение сегодня. Вот что заставило его исчезнуть для меня (в конструкторе интерфейсов)

1. Установите для поля высоты строки для представления таблицы значение, отличное от 44 2 Установите для поля высоты строки для ячейки tableView значение, отличное от 44

Мне не пришлось вносить никаких изменений в код


3

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

Я добавление подвидов и ограничений в UITableViewCell«S initметод , как это:

addSubview(rankingLabel)
addConstraints(cellConstraints)

Я решил проблему, добавив их в ячейку contentView:

contentView.addSubview(rankingLabel)
contentView.addConstraints(cellConstraints)

1
Всегда добавляйте подпредставления в contentView, а не UITableViewCellнапрямую.
dinesharjani 05

3

Установите расчетную высоту строки на ноль, и предупреждение исчезнет:

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


Настоящая проблема в том, что где-то отсутствует ограничение. Вы, вероятно,
вводите

1

Я тоже испытал это предупреждение при переходе на Xcode 6 GM. Я получил предупреждение только тогда, когда повернул устройство в исходное положение.

Я использую пользовательские UITableViewCells. Для представления таблицы раскадровки задан мой нестандартный размер (в моем случае 100,0). Хотя ячейки таблицы отображаются правильно, как и в предыдущих выпусках, мне не понравилось предупреждающее сообщение.

В дополнение к приведенным выше идеям я добавил это

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100.0;
}

Экран отображает ... реагирует на вращение и больше никаких предупреждающих сообщений.


Итак, я попытался использовать ваш метод, используя строку, которую вы мне дали, но все равно обнаружил ту же ошибку. Я также не использовал ротацию в своем приложении.
Дэвид Э

1

В xcode 6.0.1 я удалил это предупреждение, указав высоту строки, используя:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44.0;
}

1

Если вы создали Custom tableViewCell для tableView, убедитесь, что вы указали как нижние, так и верхние ограничения для своих ячеек, вы также можете получить это сообщение, если ваши подпредставления внутри пользовательских ячеек выровнены по центру Y, что не вызовет никаких сообщений об ошибках, но приведет к беспорядку вверх с определением высоты строки для tableview по очереди, как на изображении, которое я прикрепил, здесь у нас есть как верхние, так и нижние ограничения

Когда вы создаете пользовательскую ячейку для tableView, вы должны указать высоту строки или верхние и нижние ограничения для пользовательских подпредставлений ячейки внутри ячейки (например, метка в пользовательской ячейке, как на изображении ниже)

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

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


0

В раскадровке установите cell Row heightполе с тем же значением, что и Row heightв tableView(у меня оба с одинаковым значением работали).

Если вы добавите heightForRowAtIndexPathфункцию в свой код, это может вызвать проблемы с производительностью, потому что она будет вызываться для каждой ячейки, поэтому будьте осторожны.


0

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


0

У меня была эта проблема, когда мои метки и представления в настраиваемом tableViewCell были ограничены customCell, а не его Content View. Когда я снял ограничения и подключил их к ячейкам Content View, проблема была решена.


0

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


0

Если вы производите динамический расчет высоты,

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

0

У меня также есть аналогичная проблема для пользовательской ячейки tableview, которая имеет динамическую высоту строки. Динамическая высота не отражалась, и в консоли появилось такое же предупреждение. Решение заключается в добавлении подпредставлений в ячейку вместо contentView. Кстати, я создал подпредставления программно.


0

У меня есть эта проблема с TableViewCells, где ограничения устанавливаются при инициализации, но где содержимое ячейки загружается впоследствии, это означает, что механизм автоматического размещения не может определить высоту. Другие решения здесь не работают, потому что мне нужна высота ячейки UITableView.automaticDimension.

Я просто добавил в ячейку дополнительное ограничение:

contentView.heightAnchor.constraint(equalToConstant: 44, priority: .defaultLow)

0

Я получил это предупреждение сегодня Все, что я сделал, это просто добавил одну дополнительную строку в свой код

tableView.rowHeight = 200;

добавьте эту строку кода внутри

func tableView(_ tableView: UITableView, numberOfRowsInSection section:Int) -> Int {
  ...
}

и окончательный код выглядит как

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  tableView.rowHeight = 200;
  ...
}

этот код увеличит высоту ячейки строки таблицы до 200, высота по умолчанию - 44


-1

У меня такая же ошибка, из-за этой строки была показана эта ошибка.

self.layer.backgroundColor = UIColor (white: 1, alpha: 0.2) as! CGColor

Я просто меняю строку, как показано ниже, чтобы исправить ошибку

self.layer.backgroundColor = UIColor (белый: 1, альфа: 0,2) .cgColor

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.