Подтвердить что ты не робот

Проблема ограничения автозапуска с неожиданной NSAutoresizingMaskLayoutConstraint

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

"<NSAutoresizingMaskLayoutConstraint:0x82da910 h=--& v=--& V:[UITableViewCellContentView:0x82d9fb0(99)]>"

Я поставил некоторый пример кода для воспроизведения https://github.com/nicolasccit/AutoLayoutCellWarning

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

"H:|-padding-[_imageThumbnail(==imageWidth)]-[_labelName]";
"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";
"V:|-padding-[_labelName]";

На обоих элементах для параметра AutoresizingMaskIntoConstraints задано значение NO.

И я получаю следующее исключение:

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:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-|   (Names: '|':UITableViewCellContentView:0xa6e4150 )>",
    "<NSLayoutConstraint:0xa6e4f10 V:[UIImageView:0xa6e4340(80)]>",
    "<NSLayoutConstraint:0xa6e4ed0 V:|-(10)-[UIImageView:0xa6e4340]   (Names: '|':UITableViewCellContentView:0xa6e4150 )>",
    "<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0xa6e4f90 V:[UIImageView:0xa6e4340]-(10)-|   (Names: '|':UITableViewCellContentView:0xa6e4150 )>

Я знаю, что последнее ограничение связано с представлением содержимого, но я неясно, как правильно его удалить (Настройка | AutoresizingMaskIntoConstraints в NO на contentView вызывает ошибку, а в SO-ссылке ниже, это испортит весь макет):

<NSAutoresizingMaskLayoutConstraint:0xa6e4ac0 h=--& v=--& V:[UITableViewCellContentView:0xa6e4150(99)]>

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

Я считаю, что ограничения, которые я определяю, являются действительными и довольно простыми, но не могут понять, что происходит. И я вижу исключение, которое возникает как в iOS 6.1, так и в iOS 7.

Любая идея, что я делаю неправильно здесь?

Спасибо, Николя

4b9b3361

Ответ 1

Я поместил исправленную версию вашего кода в https://github.com/mattneub/AutoLayoutCellWarning. Работает отлично. Эта линия была основной причиной ваших проблем:

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail(==imageHeight)]-padding-|";

Измените это на

NSString *const kImageVertical = @"V:|-padding-[_imageThumbnail]-padding-|";

И все будет хорошо.

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

У меня есть еще одна критика вашего кода. При попытке выполнить динамическую настройку высоты ячейки при использовании автоматического макета, вы давали команды обновления макета и ограничения, которые вы никогда не должны давать, и вы даете им не в то время. Можно создавать динамические высоты строк на основе ограничений, но то, как вы это делаете, не так. Все, что вам нужно сделать, это вызвать systemLayoutSizeFittingSize, чтобы узнать правильную высоту ячейки. Кроме того, нет абсолютно никакой необходимости вставлять вашу "скрытую" ячейку в интерфейс. Не делай этого; это просто путает вещи. Одна из вещей, которые вы заметите при просмотре моей версии кода, состоит в том, что она намного проще, чем ваша, из-за этих различий.

Для рабочего метода см. мой пример в https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch08p424variableHeights/ch21p722variableHeights/RootViewController.m

И рассмотрим обсуждение этой проблемы в моей книге.

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

Ответ 2

Вы должны прочитать описание исключения более подробно:

Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints

Короче говоря, это ограничение, которое вы видите, связано с некоторым UIView, если он translatesAutoresizingMaskIntoConstraints установлен на YES. В этом случае я подозреваю, что это представление содержимого ячейки, на что указывает UITableViewCellContentView.

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

cell.contentView.translatesAutoresizingMaskIntoConstraints = NO

EDIT: Теперь имейте в виду, что это временное исправление, скорее всего, у вас есть другая логическая ошибка с вашими ограничениями, например, сдерживание чего-то в contentView ячейки самой ячейке. Или, казалось бы, заставляя contentView быть больше, чем ячейка (и, следовательно, больше, чем ее "автоматическая калибровка" ).

Например, ваша клетка достаточно высокая? то есть он достаточно высок, так что contentView составляет 100 футов в высоту? Обратите внимание, что contentView должен быть таким высоким, что может не совпадать с высотой ячейки.