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


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 ? Вибачте, що це випадково, але вдячний би вашим порадам щодо чогось автоматичного макета, спасибі!
чезнеад

Відповіді:


275

Я б рекомендував налагоджувати помилку і знаходити обмеження, яке " є тим, кого ви не хочете" . Припустимо, у вас є такий випуск:

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

Завжди проблема полягає в тому, як знайти наступні обмеження та погляди.

Як зробити це два рішення:

  1. ВІДНОСЛІДЖЕННЯ ВІДПОВІДЖЕННЯ ІЄАРАРХІЇ (Не рекомендую цей спосіб)

Оскільки ви знаєте, де знайти несподівані обмеження (PBOUserWorkDayHeaderView), є спосіб зробити це досить добре. Давайте знайдемо UIViewі NSLayoutConstraintв червоних прямокутниках. Оскільки ми знаємо їх ідентифікатор в пам'яті, це досить легко.

  • Зупиніть додаток за допомогою ієрархії перегляду налагодження :

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

  • Знайдіть належний 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
    }
}

ЗАВДАННЯ-С

@interface NSLayoutConstraint (Description)

@end

@implementation NSLayoutConstraint (Description)

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

@end
  • побудуйте його ще раз, і тепер у вас є більш читабельний вихід для вас:

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

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

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

  • і швидко знайдіть його:

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

ЯК ПРОСТИЙ ФІКС ТАКИЙ СПРАВ?

  • спробуйте змінити пріоритет на 999порушене обмеження.

Це щойно виправило мою помилку ... велике спасибі. Як би ви це зробили для об'єктивного c? Додати категорію?
чезнеад

Thx для рішення, але чи можу я використовувати розширення в цілі c?
dev.nikolaz

Чи такий ідентифікатор такий, як ідентифікатор accessibilityIdentifier, який доступний на програмах UIViews програмно. Якщо ні, як можна встановити ідентифікатор програмно?
Арунах Дас

@Да, ні, це не те саме. Прочитайте цю відповідь
Bartłomiej Semańczyk

3
Мені подобається другий спосіб, і я вважаю, що це найкращий спосіб простежити порушене обмеження
Antarix

108

Проблема, яка у вас виникає, полягає в тому, що NSAutoresizingMaskLayoutConstraints не повинно бути там. Це стара система пружин і підкосів. Щоб позбутися від нього, запустіть цей метод на кожному перегляді, який ви хочете обмежити:

[view setTranslatesAutoresizingMaskIntoConstraints:NO];

5
які причини для того, щоб перегляд взагалі не з’явився при встановленні значення setTranslatesAutoresizingMaskIntoConstraints на NO?
topwik

1
як приклад, я створюю SSBadgeView (UIView), додаю podView imageView до SSBadgeView, а потім додаю SSBAdgeView як підпогляд до UIReuseableView. Я додаю деякі обмеження до SSBadgeView та setTranslatesAutoresizingMaskIntoConstraints: НЕ в SSBadgeView. зображення subView SSBadgeView викладено так, як очікувалося, але батьківського SSBadgeView зображення ніде не було помічено.
topwik

1
Ви забули відключити TranslatesAutoresizingMaskIntoConstraints у своїх
підпоглядах

Це відбувається, коли я встановлюю це властивість, drive.google.com/file/d/0BxuYs8WHXCF7bV9ndHFrQ0dMYVE/… я використовую цей кодовий рядок: [self.contentView setTranslatesAutoresizingMaskIntoConstraints: NO]; for (перегляд 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] ...

Це було б затяжним горизонтальним обмеженням тощо.


6

У мене було викинуто досить багато цих винятків. Найшвидший і найпростіший спосіб вирішити їх - знайти унікальні значення у винятках, які я шукав у вихідному коді розкадровки. Це допомогло мені знайти фактичний перегляд (і) та обмеження (и), що спричиняють проблему (я використовую змістовні користувацькі мітки на всіх переглядах, що полегшує відстеження обмежень та поглядів) ...

Отже, використовуючи вищевикладені винятки, я б відкрив розкадровку як "вихідний код" у xcode (або іншому редакторі) і шукав би щось, що можу знайти ...

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

.. це виглядає як вертикальне (V) обмеження на UILabel зі значенням (17).

Переглядаючи винятки, я також знаходжу

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

Схоже, що UILabel (0x72bf7c0) близький до UIButton (0x886efe0) з деяким вертикальним інтервалом (8).

Цього, сподіваюсь, мені буде достатньо, щоб знайти конкретні погляди у вихідному коді розкадрівки (можливо, за допомогою пошуку тексту "17" спочатку) або принаймні кількох ймовірних кандидатів. Звідти я маю змогу реально розібратися, які їхні погляди є у дошці розкадрівки, що полегшить ідентифікацію проблеми (шукайте «дублювання» закріплення чи закріплення, що суперечить обмеженням розміру).


"Я використовую значущі користувацькі мітки" - що таке userLabels в цьому контексті? (наприклад, як їх встановити)
Stripes

У розділі "Документ" інспектора посвідчення особи є поле "Мітка" .., яке переводиться на значення "userLabel" у вихідному коді дошки розповідей.
C Джеймс

Ви також можете встановити їх, натиснувши на вибраний вигляд на лівій панелі «Огляд» (трохи схоже на перейменування файлу у пошуку)
C James

1
Мабуть, найкраще, що я читав у вирішенні жахливого "Неможливо одночасно задовольнити обмеження". біль. Я виявив, що об'єкт, показаний у цьому пункті "Спробує відновити, порушуючи обмеження <NSLayoutConstraint:", як правило, є винуватцем, і, як каже С Джеймс, ймовірно, обмеження висоти або ширини, що суперечить обмеженням закріплення. Мені важко було зняти висоту, але, оскільки обмеження були правильними, висоту можна було збільшити з інших обмежень. Додавання обмеження по висоті просто збило з пантелику автоматичний макет, тож це я зараз шукаю.
latenitecoder

6

Мені важко було зрозуміти, які обмеження спричиняють цю помилку. Ось простіший спосіб зробити це.

Я використовую Xcode 6.1.1

  1. "Command + A", щоб вибрати всі UILabels, UIImages тощо.
  2. Клацніть Редактор -> Закріпити> (Вибрати ...) для перегляду
  3. знову натисніть Редактор -> Вирішити проблеми автоматичного макета -> Додавання відсутніх обмежень або Скидання до запропонованих обмежень. Це залежить від вашого випадку.

5

У мене виникла ця проблема, оскільки у моїх .xibфайлах використовувався режим автоматичного вимикання.

У інспекторі файлів, перша вкладка. Якщо відмітити позначку "Використовувати автоматичний розклад", вирішено проблему.

інспектор файлів автоматичного розкладу


Тож я це зробив, і це вирішило проблему, але "UIImageView", який у мене був у верхній частині екрана (який я використовував як панель навігації) перемістився до нижньої частини екрана. Чи знаєте ви, чому це сталося?
dietbacon

1
Autolayout використовує обмеження для управління компонуванням об'єктів. Оскільки ви тільки що відключили автоматичний розклад, ці обмеження, швидше за все, зникли, і тому ваше положення UIImageViewзмінилося. Ви повинні встановити цю позицію ще раз, або програмно, або за допомогою Інтерфейсу.
Stéphane Bruckert

5

Ось мій досвід та рішення. Я не торкнувся коду

  1. Виберіть перегляд (UILabel, UIImage тощо)
  2. Редактор> Прикріпити> (Вибрати ...) для перегляду
  3. Редактор> Вирішіть проблеми з автоматичною розкладкою> Додати пропущені обмеження

4

використовувати швидкий цей код

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 .

Тому вам доведеться видалити обмеження за замовчуванням, перш ніж планувати додавати нове.


1

Для мене головною причиною цієї проблеми було те, що я забув зняти прапорець AutoLayoutу Xibредакторі. Насправді я зробив багато коригувань XIBкоду.


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?

FWIW, це повідомлення про проблему з обмеженнями не виникає під час моделювання нової моделі iPad, наприклад 12,9-дюймового iPad Pro (3-е покоління). Але повідомлення з'являється під час імітації 9,7-дюймового iPad Pro ". Усі заявляють, що вони мають iOS 12.1.


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.

0

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


-1

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

myView.removeConstraint(theConstraint)

насправді нічого не видаляли, бо мені потрібно було дзвонити

myView.superView.removeConstraint(theConstraint)

оскільки обмеження було технічно рідним обмеженням мого погляду.


-4

стрімкий 4

Я просто додаю цей рядок у viewDidLoad і добре працює зі мною.

view.removeConstraints(view.constraints)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.