iOS8 - ограничения неоднозначно предполагают нулевую высоту


100

Кто-нибудь знает, как это отладить?

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

Строки имеют фиксированную высоту, установленную

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

И все constraintsвроде бы счастливы ...

Ответы:


129

В моем случае при установке высоты возврата и расчетной высоты предупреждение исчезло.

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

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

Другое решение, когда вам не нужны два переопределения, - просто использовать self.tableView.rowHeight = 44;в вашем loadViewметоде или init.


1
У меня есть несколько строк типа в разделе, и только одна из них имеет динамическую высоту. тогда это не работает
Радж Аггравал

Если мы установим высоту по умолчанию в xib / storyboard, нам не нужно реализовывать эти методы.
Satyam

77

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


2
Это сработало для меня. Я просмотрел все ячейки контейнера и удостоверился, что хотя бы одно подпредставление имеет ограничение «верхнее пространство для контейнера» и «нижнее пространство для контейнера».
Rog182

7
Это правильный ответ для iOS 8 при использовании ячеек представления таблицы с саморазмером.
tsafrir 04

1
Вы имеете в виду ограничения от элементов внутри представления содержимого до верха и низа представления содержимого?
Зак Шапиро

Я пробовал это, но все время получаю предупреждение о конфликте ограничений.
Шириш Кумар

2
Убедитесь, что вы добавляете верхнее и нижнее ограничение в представление содержимого ячейки, а не в саму ячейку. Если вы добавите ограничение к ячейке, код все равно будет работать, но попытается использовать высоту 0.
fr

26

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

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

NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);

Будет напечатан длинный список разделов и строк, но ошибка появится сразу после конкретной ячейки, вызывающей ошибку, и вы сможете быстро определить, какая ячейка вызывает проблему, и соответствующим образом исправить свои ограничения. Это особенно полезно для статических ячеек. Переопределение высоты с помощью введенного вручную числа будет работать, если вы не используете autoLayout и автоматическую высоту ячеек, но по существу отключит эти функции, что является очень плохим решением, если вы пытаетесь это использовать.

Если вы ранее не использовали метод heightForRowAtIndexPath, но хотите отладить эту ошибку, не отменяя настройку UITableViewAutomaticDimension, просто добавьте это в свой код:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);
    return UITableViewAutomaticDimension;
}

Большое спасибо. Это мне очень помогло. Сначала я подумал, что проблема связана с другой ячейкой табличного представления. После отладки выяснилось, что проблема была в другом.
akozin 03

Я бы хотел это сделать, но длинные, раздел и строка не определены. Не могли бы вы уточнить, что это должно быть в Swift?
DrWhat

9

Похоже, что в XCode 6.1 есть ошибка, которая вызывает эту проблему, если используется автоматическая компоновка, и вы не указываете значение высоты строки для каждой ячейки представления таблицы, а вместо этого оставляете значение «по умолчанию». Если просто установить флажок «Пользовательский» рядом с высотой строки для каждой ячейки, предупреждение исчезнет.


2
Если вы используете ячейки с изменяющимся размером, вам нужно оставить высоту строки по умолчанию.
phatmann

1
Это решило предупреждение. Но я считаю, что он появляется только при использовании статических ячеек в TableView
MontiRabbit

1
@phatmann Эта проблема возникает только для статических ячеек, поэтому ячейки не должны изменяться самостоятельно.
ltm

@ltm может ли саморазмерные ячейки бесполезны в статических ячейках, если пользователь, возможно, увеличил текст? (Вы знаете, в разделе специальных возможностей в настройках iPhone)
Байрон Кутси

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

3

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


3

Ограничения могут быть приемлемы для макета, но не подходят для автоматической высоты строки. Удачный макет будет означать, что контент может быть размещен без двусмысленности. Это удовлетворило бы проверки в Интерфейсном Разработчике.

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

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


3

Я использовал высоту строки 43 (или <> 44) в инспекторе размеров табличного представления, и ошибка исчезла. Используя 44, я получаю ошибку. Xcode версии 6.0.1.

- Этот ответ был удален модератором, пожалуйста, не делайте этого, это решает проблему. Это РЕШАЕТ проблему для меня и может сделать то же самое для других. Не могли бы вы снова его не удалять.


2

Мне не удалось удалить предупреждение, но для того, чтобы ограничения работали, я установил для свойства tableview новое для iOS8 estimatedRowHeightзначение фиксированной высоты и удалил heightForRowAtIndexPathреализацию.


Если он не удалил предупреждение, то это система, которая восполняет отсутствующее ограничение и устанавливает высоту строки == для свойства cell.rowHeight. Предупреждение касается свойства автоматического лечения, если оно автоматически лечит, значит, проблемы не было?
Педро Борхес

2

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

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

Вы можете отключить автоматический макет в построителе интерфейса, сняв флажок «Использовать автоматическое размещение» в инспекторе файлов справа.

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

Вертикальные ограничения

  1. Ограничение вертикального пространства между верхней частью представления содержимого и верхней частью метки
  2. Ограничение фиксированной высоты метки
  3. Ограничение вертикального пространства между нижней частью метки и нижней частью представления содержимого

Горизонтальные ограничения

  1. Ограничение по горизонтали между передним краем представления содержимого и передним краем этикетки
  2. Ограничение фиксированной ширины метки
  3. Ограничение по горизонтали между задним краем метки и задним краем представления содержимого

Я использую ограничения, и все они кажутся счастливыми, как упоминалось в вопросе.
Крис

Существуют ли эти ограничения для подвидов представления содержимого ячейки? На что они похожи? Неужели у вас есть разные клетки? Если вы определяете ячейки с фиксированной высотой с помощью решений Фредерика Боннера, ограничения переопределяются.
wrightak

1

Вы можете использовать AutoLayout, чтобы рассчитать правильную высоту. Вот хороший пост о динамической высоте ячейки в iOS 8: http://natashatherobot.com/ios-8-self-sizing-table-view-cells-with-dynamic-type/


Я бы хотел, чтобы это было так просто. Добавление этих двух строк, к сожалению, не устранило мою проблему с автоматическим изменением размера
Зак Шапиро

1

В Swift принудительная высота возврата устранила мою проблему:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if(indexPath.row == 0){
       return CGFloat(131.0)
    }else if(indexPath.row == 8){
       return CGFloat(97.0)
    }else{
       return CGFloat(44.0)
    }
}

1

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

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

В контроллере представления вашей таблицы.


1

Я использовал mapView внутри uitableviewcell. Я изменил высоту просмотра карты на 1/3 размера экрана устройства. У меня такая же ошибка. Я исправил ошибку, добавив недостающие ограничения в представление содержимого uitableviewcell.

1) Снимите ограничения contentView.

2) Установите для параметра «Сбросить рекомендуемые константы» значение contentView.

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

3) Добавьте недостающие ограничения - если есть

4) Мы убеждаемся, что представление содержимого имеет все необходимые ограничения. введите описание изображения здесь


0

В моем случае это потому, что я проектирую ячейку с помощью xib и забываю добавить этот xib-файл к цели.

После того, как я добавлю этот xib-файл к цели, проблема исчезнет


0

Хотя ответы на этой странице, в которых обсуждается добавление ограничений высоты или ручной возврат rowHeights, например 44 в heightForRowAtIndexPath, вызывают исчезновение предупреждения, они излишни, поскольку это ошибка в Xcode, видимая по крайней мере в версии 6.3.2 (6D2105).

Если вы установите точку останова в viewDidLoad, вы увидите, что self.tableView.rowHeight = -1 (UITableViewAutomaticDimension), даже если вы укажете высоту строки 44 в раскадровке. Это связано с тем, что Apple ошибочно предполагает, что вам нужна динамическая высота строк, если вы оставите высоту строки равной 44, потому что они не предоставили вам флаг для указания ваших предпочтений.

Вот несколько возможных решений и их результатов:

  • Установите высоту строки 43 или 45 в раскадровке (работает).

  • Вручную вернуть высоту 44 в heightForRowAtIndexPath (работает).

  • Добавьте ограничения по высоте между элементами UITableViewCell и его contentView (работает).

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

  • Установите высоту каждого UITableViewCell на 44 (Custom) в раскадровке (сбой).

Мне действительно нужно было чистое решение для раскадровки, поэтому, наконец, я попробовал:

  • Добавьте определяемый пользователем атрибут среды выполнения в UITableView в раскадровке и назовите UITableView с примечанием о том, как устанавливается его rowHeight, чтобы будущие разработчики могли его найти: (работает):

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

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

Эти ошибки слишком распространены в разработке под iOS и заставляют разработчиков тратить много времени на взвешивание последствий того, как их решения повлияют на ремонтопригодность в долгосрочной перспективе.

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


0

Я думаю, здесь происходят две важные вещи.

1) Очень легко сделать ограничения неправильными, если вы перетаскиваете ctrl +. Итак, дважды проверьте, что вы все сделали правильно. Лучше всего использовать лоток в левой части экрана, чтобы нарисовать эти ограничения.

2) Вместо того, чтобы указывать оцениваемыйRowHeight в ViewDidLoad или где-то еще, используйте метод делегата

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {}

Это сразу устранило проблему для меня.


Почему вы используете переопределение?
FractalDoctor

0

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

Apple, похоже, исправила это для iOS9. Ошибка произошла только на 8.4 для меня.


0

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

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