iOS8 - ограничения неоднозначно предполагают высоту нуля
У кого-нибудь есть идеи, как это отладить?
Только предупреждение один раз: обнаружен случай, когда ограничения неоднозначно указывают высоту нуля для представления содержимого ячейки табличного представления. Мы рассматриваем развал непреднамеренно и вместо этого используем стандартную высоту.
Строки имеют фиксированную высоту, установленную
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 34.0;
}
И все constraints
кажется счастливым...
17 ответов
Принудительное возвращение высоты и предполагаемой высоты заставило предупреждение исчезнуть в моем случае.
- (CGFloat)tableView:(UITableView *)tableView
estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
Другое решение, в котором вам не нужны два переопределения, - это просто использовать self.tableView.rowHeight = 44;
в вашем loadView
или метод инициализации.
Что также можно сделать, это добавить вертикальные ограничения сверху и снизу представления содержимого. Это сделает автопутешествие счастливым (потому что теперь он знает, как рассчитать высоту ячейки).
Если вы используете ограничения 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;
}
Кажется, в XCode 6.1 есть ошибка, которая вызывает эту проблему при использовании автоматического макета, и вы не указываете значение для высоты строки для каждой ячейки табличного представления, а вместо этого оставляете значение "по умолчанию". Просто установив флажок "Пользовательский" рядом с высотой строки, для каждой ячейки, предупреждение исчезнет.
Ограничения могут быть полезны для макета, но не могут использоваться для автоматической высоты строки. Удачный макет будет означать, что контент может быть выложен без двусмысленности. Это будет соответствовать проверкам в Интерфейсном Разработчике.
Удачная компоновка для автоматической высоты строки будет означать, что, в дополнение к вышесказанному, вы также включаете ограничения для нижней части ячейки.
Подробнее здесь: Обнаружен случай, когда ограничения неоднозначно указывают высоту ноль
Да, вы получаете все ограничения "счастливыми", даже если у вас есть только горизонтальные ограничения для элементов в ячейке табличного представления. У меня была такая же проблема. Вам нужно добавить также вертикальные ограничения. При этом это предупреждение исчезнет.
Я использовал Row Height 43 (или <> 44) в Инспекторе размеров табличного представления, и ошибка исчезла. Используя 44 я получаю ошибку. Версия Xcode 6.0.1.
- Этот ответ был удален модератором, пожалуйста, не пытайтесь решить проблему. Это решает проблему для меня и может сделать это для других тоже. Не могли бы вы удалить его снова?
Если вы получаете это предупреждение, скорее всего, потому что вы используете автоматическое расположение, и ваши ячейки не имеют никаких ограничений внутри них.
Вы должны либо прекратить использование автоматического размещения, либо реализовать ограничения, которые однозначно определяют высоту ячеек.
Вы можете отключить автоматическое расположение в конструкторе интерфейса, сняв флажок "Использовать автоматическое расположение" в инспекторе файлов справа.
Если вы решите использовать автоматическую разметку, а высота ваших ячеек будет фиксированной, внедрение соответствующих ограничений должно быть простым. Просто добавьте ограничения по высоте для подпредставлений представления содержимого ячейки и реализуйте вертикальные ограничения пространства между подпредставлениями, а также между подпредставлениями и представлением содержимого. Например, если ваша ячейка имеет одну метку, это будет работать:
Вертикальные ограничения
- Вертикальное ограничение пространства между верхней частью представления содержимого и верхней частью метки
- Исправлено ограничение высоты надписи
- Вертикальное ограничение пространства между нижней частью метки и нижней частью представления содержимого
Горизонтальные ограничения
- Горизонтальное ограничение пространства между передним краем представления содержимого и передним краем метки
- Исправлено ограничение ширины надписи
- Горизонтальное ограничение пространства между задней кромкой метки и задней кромкой представления содержимого
Мне не удалось удалить предупреждение, но чтобы заставить работать ограничения, я установил новое свойство iOS8 для tableview. estimatedRowHeight
до фиксированной высоты, и удалены heightForRowAtIndexPath
реализация.
Для стандартного исправления болота - без ограничений, без оценки высоты или чрезмерного решения проблемы. Я создал проект по умолчанию, подключил табличное представление, но забыл поместить делегат высоты в контроллере представления. Чтобы просто убрать это предупреждение, вам нужно это.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 44;
}
В контроллере представления вашей таблицы.
Вы можете использовать AutoLayout, чтобы рассчитать правильную высоту для вас. Вот хороший пост о динамической высоте ячейки на iOS 8: http://natashatherobot.com/ios-8-self-sizing-table-view-cells-with-dynamic-type/
Я использовал mapView внутри uitableviewcell. Я изменил высоту просмотра карты на 1/3 размера экрана устройства. Я получил ту же ошибку. Я исправил ошибку, добавив отсутствующие ограничения в представление содержимого uitableviewcell.
1) Очистить ограничения contentView.
2) Установите Сброс в Рекомендуемые константы для ContentView.
3) Добавить недостающие ограничения - если есть
4) Мы следим за тем, чтобы представление контента имело все необходимые ограничения.
В 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)
}
}
Хотя ответы на этой странице, обсуждающие добавление ограничений по высоте или возврат вручную rowHeights, например, 44 в heightForRowAtIndexPath, приводят к тому, что предупреждение исчезает, они излишни, поскольку это ошибка в XCode, видимая по крайней мере в версии 6.3.2 (6D2105).
Если вы установите точку останова в viewDidLoad, вы увидите, что self.tableView.rowHeight = -1 (UITableViewAutomaticDimension), даже если вы укажете высоту строки 44 в раскадровке. Это связано с тем, что Apple неверно полагает, что вам нужна динамическая высота строки, если вы оставите высоту строки равной 44, потому что они не предоставили вам флаг для указания ваших предпочтений.
Вот некоторые возможные решения и их результаты:
Установите высоту строки на 43 или 45 в раскадровке (работает).
Вручную верните высоту 44 в высоту ForRowAtIndexPath (работает).
Добавьте ограничения по высоте между элементами UITableViewCell и его contentView (работает).
К сожалению, эти решения требуют, чтобы вы изменили свой дизайн, добавили ненужные ограничения или добавили ненужный код, чтобы обойти ошибку. Я попытался (что я думал) самое простое решение:
- Установите высоту каждого UITableViewCell на 44 (Пользовательский) в раскадровке (не удается).
Я действительно хотел чистого раскадровки для этого, так что, наконец, я попытался:
- Добавьте пользовательский атрибут времени выполнения к UITableView в раскадровке и назовите UITableView примечанием о том, как его rowHeight устанавливается, чтобы его могли найти будущие разработчики: (работает):

Эти ошибки слишком распространены в разработке для iOS и вынуждают разработчиков тратить слишком много времени на то, чтобы оценить, как их решения повлияют на удобство обслуживания в долгосрочной перспективе.
Так как найти концептуально правильное решение, которое можно обслуживать и которое не кажется запутанным, так неуловимо, и если предположить, что Apple исправит ошибку и что 44 станет высотой строки по умолчанию в обозримом будущем, тогда ограничение или пользовательское определение Решения атрибутов времени выполнения, вероятно, являются наиболее поддерживаемыми.
Я также видел эту ошибку при использовании универсальных раскадровок или XIBS. Если вы пренебрегаете указанием надлежащих ограничений для класса размера Any x Any, я видел эту ошибку.
Apple, кажется, исправил это для iOS9. Ошибка произошла только на 8.4 для меня.
Я думаю, что здесь происходят две важные вещи.
1) Очень просто сделать ограничения неправильными, если вы удерживаете Ctrl + перетаскивание. Итак, дважды проверьте, что у вас все сделано правильно. Лучше всего использовать лоток в левой части экрана, чтобы нарисовать эти ограничения.
2) Вместо того, чтобы указывать предполагаемый вес в ViewDidLoad или где-либо еще, используйте метод делегата
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {}
Это сразу решило проблему для меня.
В моем случае это потому, что я проектирую ячейку с помощью xib, и я забываю добавить этот файл xib к цели.
После того, как я добавляю этот xib-файл к цели, проблема исчезла
В течение нескольких дней я обходил эту ошибку и другую ошибку, в которой создавались ограничения (не знаю, где), которые противоречили ограничениям, которые я хотел. У меня даже это работало в одном случае, когда все видимые свойства были идентичны другим. Единственное решение, которое я нашел, заключалось в том, чтобы перейти на атомарность - создать совершенно новый файл с помощью xib и снова начать заново подключать розетки, копируя старый код. Возможно, это не лучшее решение, но иногда, если проблема не видна, делать больше нечего. По крайней мере, переход на атомарный уровень - хороший способ проанализировать, что происходит.