Невозможно одновременно удовлетворить ограничения, попытается восстановить, нарушив ограничение

145

Ниже приведено сообщение об ошибке, которое я получаю в области отладки. Он работает нормально и ничего плохого, кроме того, что я получаю эту ошибку. Это помешало бы Apple принять приложение? Как мне это исправить?

2012-07-26 01:58:18.621 Rolo[33597:11303] Unable to simultaneously satisfy constraints.
    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) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x887d630 h=--& v=--& V:[UIButtonLabel:0x886ed80(19)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x887d5f0 h=--& v=--& UIButtonLabel:0x886ed80.midY == + 37.5>",
    "<NSAutoresizingMaskLayoutConstraint:0x887b4b0 h=--& v=--& V:[UIButtonLabel:0x72bb9b0(19)]>",
    "<NSAutoresizingMaskLayoutConstraint:0x887b470 h=--& v=--& UIButtonLabel:0x72bb9b0.midY == - 0.5>",
    "<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]>",
    "<NSLayoutConstraint:0x72c2430 UILabel:0x72bfad0.top == UILabel:0x72bf7c0.top>",
    "<NSLayoutConstraint:0x72c2370 UILabel:0x72c0270.top == UILabel:0x72bfad0.top>",
    "<NSLayoutConstraint:0x72c22b0 V:[UILabel:0x72bf7c0]-(NSSpace(8))-[UIButton:0x886efe0]>",
    "<NSLayoutConstraint:0x72c15b0 V:[UILabel:0x72c0270]-(NSSpace(8))-[UIRoundedRectButton:0x72bbc10]>",
    "<NSLayoutConstraint:0x72c1570 UIRoundedRectButton:0x72bbc10.baseline == UIRoundedRectButton:0x7571170.baseline>",
    "<NSLayoutConstraint:0x72c21f0 UIRoundedRectButton:0x7571170.top == UIButton:0x886efe0.top>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]>

Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Джонни Кокс
источник
1
Эта ошибка будет происходить только в Xcode 4.5, поэтому вы все равно не можете отправить ее в App Store (пока она не будет выпущена)
borrrden
Так что тут нет ничего плохого? И можно ли будет использовать другую версию xcode для отправки в магазин приложений?
Джонни Кокс
1
Да, что-то не так, но это не имеет значения, потому что это связано с функцией iOS, которая еще не доступна в публичных версиях Xcode. Если он компилируется с 4.4, вы можете выпустить его, используя эту версию (она была выпущена сегодня).
Borrrden
Я получаю это сообщение об ошибке для приложений OS X в Xcode 4.4. Я не понимаю это
Стив Маклеод
@ Bartłomiej Semańczyk Не могли бы вы случайно присоединиться к комнате: chat.stackoverflow.com/rooms/92522/autolayout-and-ios ? Извините, это случайно, но был бы признателен за совет по поводу автоматического макета, спасибо!
Cheznead

Ответы:

275

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

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

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

Есть два решения, как это сделать:

  1. ИЕРАРХИЯ ОТСУТСТВИЯ ОТЛАДКИ (не рекомендую таким образом)

Поскольку вы знаете, где найти неожиданные ограничения (PBOUserWorkDayHeaderView), есть способ сделать это довольно хорошо. Найдем UIViewи NSLayoutConstraintв красных прямоугольниках. Так как мы знаем их идентификатор в памяти, это довольно легко.

  • Остановите приложение, используя Debug View Hierarchy :

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

  • Найти правильный UIView:

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

  • Следующее - найти NSLayoutConstraint, о котором мы заботимся:

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

Как видите, указатели памяти одинаковы. Итак, мы знаем, что происходит сейчас. Дополнительно вы можете найти NSLayoutConstraintв иерархии представления. Так как он выбран в представлении, он также выбран в навигаторе.

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

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

(lldb) po 0x17dce920
<UIView: 0x17dce920; frame = (10 30; 300 24.5); autoresize = RM+BM; layer = <CALayer: 0x17dce9b0>>

Вы можете сделать то же самое для каждого ограничения, на которое вам указывает отладчик :-) Теперь вы решаете, что делать с этим.

  1. Напечатайте это лучше (я действительно рекомендую этот способ, это из Xcode 7)

    • установить уникальный идентификатор для каждого ограничения в вашем представлении:

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

  • создать простое расширение для NSLayoutConstraint:

SWIFT :

extension NSLayoutConstraint {

    override public var description: String {
        let id = identifier ?? ""
        return "id: \(id), constant: \(constant)" //you may print whatever you want here
    }
}

Objective-C

@interface NSLayoutConstraint (Description)

@end

@implementation NSLayoutConstraint (Description)

-(NSString *)description {
    return [NSString stringWithFormat:@"id: %@, constant: %f", self.identifier, self.constant];
}

@end
  • соберите его еще раз, и теперь у вас есть более читаемый вывод:

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

  • как только вы получили свой, idвы можете просто нажать на него в вашем Find Navigator :

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

  • и быстро найти это:

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

КАК ПРОСТО ЧТОБЫ ИСПРАВИТЬ?

  • попытаться изменить приоритет для 999для разбитого ограничения.
Бартломей Семанчик
источник
Это просто исправило мою ошибку ... большое спасибо. Как бы вы сделали это для цели с? Добавить категорию?
Cheznead
Спасибо за решение, но могу ли я использовать расширение в цели c?
dev.nikolaz
Является ли этот идентификатор таким же, как accessibilityIdentifier, который доступен на UIViews программно. Если нет, то как можно установить идентификатор программно?
Арунабх Дас
@ Нет, это не то же самое. Прочитайте этот ответ
Bartłomiej Semańczyk
3
Мне нравится 2-й способ, и я думаю, что это лучший способ для отслеживания нарушенного ограничения
Antarix
108

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

[view setTranslatesAutoresizingMaskIntoConstraints:NO];
Дэвид Вонг
источник
5
По каким причинам представление вообще не отображается при установке для setTranslatesAutoresizingMaskIntoConstraints значения NO?
topwik
1
В качестве примера я создаю SSBadgeView (UIView), добавляю subView imageView к SSBadgeView, затем добавляю SSBAdgeView как подпредставление к UIReuseableView. Я добавляю некоторые ограничения в SSBadgeView и setTranslatesAutoresizingMaskIntoConstraints: НЕТ в SSBadgeView. Подвид изображения SSBadgeView выложен, как и ожидалось, но родителя изображения SSBadgeView нигде не видно.
topwik
1
Вы забыли отключить TranslatesAutoresizingMaskIntoConstraints в своих
подпредставлениях
Вот что происходит, когда я устанавливаю это свойство, drive.google.com/file/d/0BxuYs8WHXCF7bV9ndHFrQ0dMYVE/… Я использую эту строку кода: [self.contentView setTranslatesAutoresizingMaskIntoConstraints: NO]; для (UIView * представление в self.contentView.subviews) {[view setTranslatesAutoresizingMaskIntoConstraints: NO]; } Раньше это выглядело так: drive.google.com/file/d/0BxuYs8WHXCF7OWlvZGQwN3FlbzQ/… Хотя, надо сказать, это сработало.
rptwsthi
28

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

Например: вертикальное ограничение для трейлинга = 15, а другое -> = 10.

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

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

Кроме того, вы можете прочитать и обнаружить некоторые определенные причины прямо из журнала :

NSLayoutConstraint: 0xa338390 V: | - (15) - [UILabel: 0xa331260] (имена: '|': UILabel: 0xa330270)>

Это мы можем считать проблемой в ограничении UILabel, это ведущее вертикальное ограничение длиной 15pt.

NSLayoutConstraint: 0x859ab20 H :-( 13) - | [UIView: 0x85a8fb0] ...

Это будет горизонтальное ограничение и т. Д.

pedrouan
источник
6

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

Таким образом, используя вышеупомянутые исключения, я бы открывал раскадровку как «исходный код» в xcode (или другом редакторе) и искал что-то, что я могу найти ...

<NSLayoutConstraint:0x72bf860 V:[UILabel:0x72bf7c0(17)]> 

.. это выглядит как вертикальное (V) ограничение для UILabel со значением (17).

Просматривая исключения, я также нахожу

<NSLayoutConstraint:0x72c22b0 V:[UILabel:0x72bf7c0]-(NSSpace(8))-[UIButton:0x886efe0]>

Похоже, что UILabel (0x72bf7c0) близка к кнопке UIB (0x886efe0) с некоторым вертикальным интервалом (8) ..

Надеюсь, этого будет достаточно для того, чтобы найти конкретные представления в исходном коде раскадровки (возможно, путем поиска в тексте слова «17») или хотя бы несколько вероятных кандидатов. Оттуда я должен быть в состоянии выяснить, какие представления находятся в раскадровке, что значительно облегчит выявление проблемы (ищите «дублированный» пиннинг или пиннинг, который конфликтует с ограничениями размера).

C Джеймс
источник
«Я использую значимые пользовательские метки» - что такое пользовательские метки в этом контексте? (например, как их установить)
Полосы
В разделе «Документ» инспектора идентификации есть поле «Метка», которое переводится в значение «userLabel» в исходном коде раскадровки.
C Джеймс
Вы также можете установить их, нажав на выбранный вид на левой панели «Обзор» (немного похоже на переименование файла в Finder)
C Джеймс
1
Наверное, лучшее, что я прочитал в отношении решения страшного «Невозможно одновременно удовлетворить ограничения». боль. Я обнаружил, что объект, показанный в этой точке «Будет пытаться восстановить, нарушив ограничение <NSLayoutConstraint:», как правило, является виновником, и, как говорит С Джеймс, вероятно, ограничение высоты или ширины конфликтует с ограничениями закрепления. Мне было трудно удалить высоту, но, поскольку ограничения были правильными, высоту можно было бы извлечь из других ограничений. Добавление ограничения по высоте просто запутало автоматическую компоновку, вот что я сейчас ищу.
latenitecoder 26.09.14
6

Мне было трудно понять, какие ограничения были причиной этой ошибки. Вот более простой способ сделать это.

Я использую Xcode 6.1.1

  1. «Command + A», чтобы выбрать все UILabels, UIImages и т. Д.
  2. Нажмите Редактор -> Закрепить> (Выбрать ...), чтобы просмотреть
  3. снова нажмите «Редактор» -> «Устранить проблемы с автоматической компоновкой» -> «Добавить отсутствующие ограничения» или «Сбросить до рекомендуемых ограничений». Это зависит от вашего случая.
Ronaldoh1
источник
5

У меня была эта проблема, потому что мои .xibфайлы использовали autolayout.

В инспекторе файлов первая вкладка. Снятие отметки «Использовать Autolayout» решило проблему.

инспектор файла автоматического размещения

Стефан Брукерт
источник
Я сделал это, и это устранило проблему, но «UIImageView», который у меня был в верхней части экрана (который я использовал в качестве панели навигации), переместился в нижнюю часть экрана. Вы знаете, почему это произошло?
диетическое блюдо
1
Autolayout использует ограничения для управления макетом объектов. Поскольку вы только что отключили автопоставку, эти ограничения, скорее всего, исчезли, и поэтому ваша позиция UIImageViewизменилась. Вы должны установить эту позицию снова, либо программно, либо через Interface Builder.
Стефан Брукерт
5

Вот мой опыт и решение. Я не трогал код

  1. Выберите вид (UILabel, UIImage и т. Д.)
  2. Редактор> Закрепить> (Выбрать ...) для Superview
  3. Редактор> Устранить проблемы с автоматической компоновкой> Добавить отсутствующие ограничения
royemi
источник
4

используйте swift этот код

view.translatesAutoresizingMaskIntoConstraints = false
Арун Кумар П
источник
1
Это быстрый ответ на вопрос с меткой «цель».
Тоби Нэри
2
@SmokeDispenser Во всяком случае, я упоминал, что это быстрый код. и это работает для меня. стремительный / объективный, у него есть общее касание какао SDK.
Арун Кумар П
2

Я следовал ТАК вопросы и ответы от каждого поискового запроса. Но все они связаны с конкретным.

В основном, я имею в виду, прежде чем вы собираетесь записать формат (может быть простой), он будет предупреждать вас.

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

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

// Remove constraints if any.
[self.view removeConstraints:self.view.constraints];

Я много искал в SO, но решение было в Apple Sample Code .

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

Kampai
источник
1

Для меня главной причиной этой проблемы было то, что я забыл снять флажок AutoLayoutв Xibредакторе. На самом деле, я сделал много изменений XIBв коде.

Giuseppe
источник
1
 for(UIView *view in [self.view subviews]) {
    [view setTranslatesAutoresizingMaskIntoConstraints:NO];
}

Это помогло мне поймать вид, вызывающий проблему.

Грант Карлайл
источник
1

Ни один из предыдущих ответов не поможет в моей ситуации. Я использую XCode 10.1 и тестирую свое приложение на симуляторе для «iPad (5-го поколения)». Симулятор работает под управлением iOS 12.1.

У меня есть простое корневое представление в моей раскадровке с двумя подпредставлениями UITextField. В раскадровке нет никаких ограничений. И у меня нет объектов UIButtonBarView в приложении или раскадровке.

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

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

Unable to simultaneously satisfy constraints.
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) 
(
"<NSAutoresizingMaskLayoutConstraint:0x6000034e7700 h=--& v=--& UIKeyboardAssistantBar:0x7f9c7d714af0.height == 0   (active)>",
"<NSLayoutConstraint:0x6000034aba20 V:|-(0)-[_UIUCBKBSelectionBackground:0x7f9c7d51ec70]   (active, names: '|':_UIButtonBarButton:0x7f9c7d51de40 )>",
"<NSLayoutConstraint:0x6000034aba70 _UIUCBKBSelectionBackground:0x7f9c7d51ec70.bottom == _UIButtonBarButton:0x7f9c7d51de40.bottom   (active)>",
"<NSLayoutConstraint:0x6000034fb3e0 V:|-(0)-[_UIButtonBarStackView:0x7f9c7d715880]   (active, names: '|':UIKeyboardAssistantBar:0x7f9c7d714af0 )>",
"<NSLayoutConstraint:0x6000034fb750 V:[_UIButtonBarStackView:0x7f9c7d715880]-(0)-|   (active, names: '|':UIKeyboardAssistantBar:0x7f9c7d714af0 )>",
"<NSLayoutConstraint:0x6000034abc00 'UIButtonBar.maximumAlignmentSize' _UIButtonBarButton:0x7f9c7d51de40.height == UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide'.height   (active)>",
"<NSLayoutConstraint:0x6000034d7cf0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide']-(9)-|   (active, names: '|':_UIButtonBarStackView:0x7f9c7d715880 )>",
"<NSLayoutConstraint:0x6000034d7c50 'UIView-topMargin-guide-constraint' V:|-(10)-[UILayoutGuide:0x600002ef4e00'UIViewLayoutMarginsGuide']   (active, names: '|':_UIButtonBarStackView:0x7f9c7d715880 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000034aba70 _UIUCBKBSelectionBackground:0x7f9c7d51ec70.bottom == _UIButtonBarButton:0x7f9c7d51de40.bottom   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

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

Таким образом, остается вопрос, есть ли что-то, за что я, как разработчик приложения, отвечаю (по предположению, это куча вещей, на которые стоит обратить внимание), или это просто собственная проблема / ошибка Apple?

Кстати, это сообщение о проблеме ограничения не появляется при моделировании более новой модели iPad, такой как iPad Pro 12,9 дюйма (3-го поколения). Но сообщение появляется при моделировании iPad Pro 9,7 ". Все утверждают, что работают под управлением iOS 12.1.

jsbox
источник
1

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

Я пишу в SwiftUI для iOS 13.4

 Unable to simultaneously satisfy constraints.
        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. 
    (
        "<NSLayoutConstraint:0x2809b6760 'assistantHeight' TUISystemInputAssistantView:0x105710da0.height == 44   (active)>",
        "<NSLayoutConstraint:0x2809ccff0 'assistantView.bottom' TUISystemInputAssistantView:0x105710da0.bottom == _UIKBCompatInputView:0x10525ae10.top   (active)>",
        "<NSLayoutConstraint:0x2809cccd0 'assistantView.top' V:|-(0)-[TUISystemInputAssistantView:0x105710da0]   (active, names: '|':UIInputSetHostView:0x105215010 )>",
        "<NSLayoutConstraint:0x2809ca300 'inputView.top' V:|-(0)-[_UIKBCompatInputView:0x10525ae10]   (active, names: '|':UIInputSetHostView:0x105215010 )>"
    )

    Will attempt to recover by breaking constraint 
    <NSLayoutConstraint:0x2809ccff0 'assistantView.bottom' TUISystemInputAssistantView:0x105710da0.bottom == _UIKBCompatInputView:0x10525ae10.top   (active)>

    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
DckBrd
источник
0

Я также столкнулся с той же проблемой нарушения ограничений в журнале для viewCircle в xib. Я почти перепробовал все перечисленное выше, и у меня ничего не получалось. Затем я попытался изменить приоритет ограничения высоты, которое нарушалось в журнале (подтверждается добавлением идентификаторов для ограничений на xib), введите описание изображения здесь

Моголов
источник
-1

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

myView.removeConstraint(theConstraint)

это на самом деле ничего не удаляло, потому что мне нужно было позвонить

myView.superView.removeConstraint(theConstraint)

так как ограничение было технически родственным ограничением моего взгляда.

Адам Джонс
источник
-4

Свифт 4

Я просто добавляю эту строку в viewDidLoad и отлично работаю со мной.

view.removeConstraints(view.constraints)
Faris
источник