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

У кого-нибудь есть идеи, как это отладить?

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

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

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

И все constraints кажутся счастливыми...


person Chris    schedule 13.09.2014    source источник


Ответы (18)


Принудительная высота возврата и расчетная высота заставили предупреждение исчезнуть в моем случае.

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

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

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

person FBronner    schedule 15.09.2014
comment
У меня есть несколько строк типа в разделе, и только одна из них имеет динамическую высоту. тогда он не работает - person Raj Aggrawal; 16.09.2016
comment
Если мы установим высоту по умолчанию в xib/storyboard, нам не нужно будет реализовывать эти методы. - person Satyam; 17.02.2017

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

person MonsieurDart    schedule 25.09.2014
comment
Это сработало для меня. Я просмотрел все ячейки контейнера и убедился, что по крайней мере одно подпредставление имеет как верхнее пространство для контейнера, так и нижнее пространство для ограничения контейнера. - person Rog182; 10.10.2014
comment
Это правильный ответ для iOS 8 при использовании ячеек табличного представления с автоматическим изменением размера. - person tsafrir; 05.01.2015
comment
Вы имеете в виду ограничения от элементов внутри представления содержимого к верхней и нижней части представления содержимого? - person Zack Shapiro; 25.02.2015
comment
Я пробовал это, но я продолжаю получать предупреждение о конфликтующем ограничении. - person Shirish Kumar; 18.04.2015
comment
Убедитесь, что вы добавляете верхнее и нижнее ограничение в представление содержимого ячейки, а не в саму ячейку. Если вы добавите ограничение в ячейку, код все равно будет работать, но попытается использовать высоту 0. - person frin; 25.01.2016

Если вы используете ограничения 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;
}
person user2898617    schedule 10.04.2015
comment
Большое спасибо. Это мне очень помогло. Сначала я подумал, что проблема связана с другой ячейкой таблицы. После отладки оказалось, что проблема была в другом. - person akozin; 03.09.2016
comment
Я хотел бы сделать это, но long, section и row не идентифицированы. Не могли бы вы уточнить, что это должно быть в Swift? - person DrWhat; 05.09.2019

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

person ltm    schedule 29.10.2014
comment
Если вы используете ячейки с автоматическим размером, вам нужно оставить высоту строки по умолчанию. - person phatmann; 17.11.2014
comment
Это решило предупреждение. Но я считаю, что это появляется только при использовании статических ячеек в TableView - person MontiRabbit; 25.11.2014
comment
@phatmann Эта проблема возникает только для статических ячеек, поэтому ячейки не должны иметь собственный размер. - person ltm; 11.12.2014
comment
@ltm может быть бесполезно изменять размер ячеек в статических ячейках, если пользователь увеличил текст? (Вы знаете, в разделе специальных возможностей в настройках iPhone) - person Byron Coetsee; 14.12.2014
comment
Я думаю, что это не ошибка. Это может быть проблема с вертикальными ограничениями, они должны полностью описывать высоту ячейки, по крайней мере, для табличных представлений с автоматическим размером. - person juanjo; 25.11.2015

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

person Juraj Antas    schedule 13.10.2014

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

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

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

person Woodster    schedule 14.10.2014

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

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

person teho    schedule 18.10.2014

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

person amir    schedule 13.09.2014
comment
Если он не удалил предупреждение, то это система, которая компенсирует отсутствующее ограничение и устанавливает высоту строки == для свойства cell.rowHeight. Предупреждение касается свойства автоматического лечения, если оно автоматически исцелилось, значит, проблемы не было? - person Pedro Borges; 18.10.2014

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

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

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

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

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

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

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

  1. Горизонтальное расстояние между передним краем представления содержимого и передним краем метки
  2. Фиксированное ограничение ширины метки
  3. Ограничение горизонтального пространства между задним краем этикетки и задним краем представления содержимого
person wrightak    schedule 10.10.2014
comment
Я использую ограничения, и все они кажутся счастливыми, как упоминалось в вопросе. - person Chris; 10.10.2014
comment
Являются ли эти ограничения для подвидов представления содержимого ячейки? На что они похожи? Возможно ли, что у вас есть некоторые клетки, которые отличаются? Если вы определяете фиксированную высоту ячеек, используя решения Фредерика Боннера, ограничения переопределяются. - person wrightak; 20.10.2014

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

person ricardopereira    schedule 24.09.2014
comment
Хотел бы я, чтобы это было так просто. Добавление этих двух строк, к сожалению, не решило мою проблему с авторазмером - person Zack Shapiro; 25.02.2015

В 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)
    }
}
person King-Wizard    schedule 13.12.2014

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

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

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

person latenitecoder    schedule 31.01.2015

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

1) Очистите ограничения contentView.

2) Установите Reset to Suggested Constants в contentView.

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

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

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

person A.G    schedule 13.12.2016

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

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

person onmyway133    schedule 11.11.2014

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

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

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

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

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

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

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

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

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

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

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

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

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

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

person Zack Morris    schedule 22.06.2015

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

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

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

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

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

person Greg    schedule 23.09.2015
comment
Почему вы используете переопределение? - person FractalDoctor; 16.12.2015

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

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

person David Nix    schedule 05.01.2016

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

person DrWhat    schedule 08.08.2019