Incapable de satisfaire simultanément les contraintes, tentera de récupérer en cassant la contrainte


145

Vous trouverez ci-dessous le message d'erreur que je reçois dans la zone de débogage. Cela fonctionne bien et rien ne va pas sauf que je reçois cette erreur. Cela empêcherait-il Apple d'accepter l'application? Comment je le répare?

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
Cette erreur ne se produira que dans Xcode 4.5, vous ne pouvez donc pas la soumettre à l'App Store de toute façon (jusqu'à sa sortie)
borrrden

Alors n'y a-t-il rien de mal alors? Et serait-il possible d'utiliser une autre version de xcode pour pouvoir soumettre à l'App Store?
Johnny Cox

1
Oui, il y a quelque chose qui ne va pas, mais ce n'est pas pertinent car cela a à voir avec une fonctionnalité d'iOS qui n'est pas encore disponible dans les versions publiques de Xcode. S'il compile avec 4.4, vous pouvez le publier en utilisant cette version (il a été publié aujourd'hui).
borrrden le

Je reçois ce message d'erreur pour les applications OS X dans Xcode 4.4. Je ne comprends pas.
Steve McLeod

@ Bartłomiej Semańczyk Pourriez-vous par hasard rejoindre la salle: chat.stackoverflow.com/rooms/92522/autolayout-and-ios ? Désolé, c'est aléatoire, mais j'apprécierais vos conseils sur quelque chose lié à la mise en page automatique, merci!
cheznead

Réponses:


275

Je recommanderais de déboguer et de trouver quelle contrainte est "celle que vous ne voulez pas" . Supposons que vous ayez le problème suivant:

entrez la description de l'image ici

Le problème est toujours de savoir comment trouver les contraintes et vues suivantes.

Il existe deux solutions pour y parvenir:

  1. DEBUG VIEW HIERARCHY (Ne recommande pas cette méthode)

Puisque vous savez où trouver les contraintes inattendues (PBOUserWorkDayHeaderView), il existe un moyen de le faire assez bien. Permet de trouver UIViewet NSLayoutConstraintdans les rectangles rouges. Puisque nous connaissons leur identifiant en mémoire, c'est assez facile.

  • Arrêtez l'application à l'aide de la hiérarchie des vues de débogage :

entrez la description de l'image ici

  • Trouvez le bon UIView:

entrez la description de l'image ici

  • Le prochain est de trouver NSLayoutConstraint qui nous tient à cœur:

entrez la description de l'image ici

Comme vous pouvez le voir, les pointeurs de mémoire sont les mêmes. Nous savons donc ce qui se passe actuellement. De plus, vous pouvez trouver NSLayoutConstraintdans la hiérarchie des vues. Puisqu'il est sélectionné dans la vue, il est également sélectionné dans le navigateur.

entrez la description de l'image ici

Si vous en avez besoin, vous pouvez également l'imprimer sur la console à l'aide du pointeur d'adresse:

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

Vous pouvez faire la même chose pour chaque contrainte que le débogueur vous indiquera :-) Maintenant, vous décidez quoi faire avec cela.

  1. IMPRIMEZ-LE MIEUX (je recommande vraiment cette façon, c'est de Xcode 7)

    • définissez un identifiant unique pour chaque contrainte de votre vue:

entrez la description de l'image ici

  • créer une extension simple pour NSLayoutConstraint:

SWIFT :

extension NSLayoutConstraint {

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

OBJECTIF C

@interface NSLayoutConstraint (Description)

@end

@implementation NSLayoutConstraint (Description)

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

@end
  • compilez-le à nouveau, et maintenant vous avez une sortie plus lisible pour vous:

entrez la description de l'image ici

  • une fois que vous avez obtenu votre, idvous pouvez simplement appuyer dessus dans votre Find Navigator :

entrez la description de l'image ici

  • et trouvez-le rapidement:

entrez la description de l'image ici

COMMENT RÉPARER SIMPLEMENT CE CAS?

  • essayez de changer la priorité à 999des contraintes cassée.

Cela a corrigé mon bug ... merci beaucoup. Comment feriez-vous cela pour l'objectif c? Ajouter une catégorie?
cheznead

Thx pour la solution, mais puis-je utiliser l'extension dans l'objectif c?
dev.nikolaz

Cet identificateur est-il le même qu'accessibilitéIdentifier qui est disponible sur UIViews par programmation. Sinon, comment l'identifiant peut-il être défini par programme?
Arunabh Das

@Das non, ce n'est pas pareil. Lire cette réponse
Bartłomiej Semańczyk

3
J'aime la deuxième façon et je pense que c'est la meilleure façon de tracer une contrainte cassée
Antarix

108

Le problème que vous rencontrez est que NSAutoresizingMaskLayoutConstraints ne devrait pas y figurer. C'est l'ancien système de ressorts et entretoises. Pour vous en débarrasser, exécutez cette méthode sur chaque vue que vous souhaitez contraindre:

[view setTranslatesAutoresizingMaskIntoConstraints:NO];

5
quelles sont les raisons pour lesquelles une vue n'apparaît pas du tout lors de la définition de setTranslatesAutoresizingMaskIntoConstraints sur NO?
topwik

1
à titre d'exemple, je crée un SSBadgeView (UIView), j'ajoute une sous-vue imageView au SSBadgeView, puis j'ajoute SSBAdgeView en tant que sous-vue à un UIReuseableView. J'ajoute quelques contraintes à SSBadgeView et setTranslatesAutoresizingMaskIntoConstraints: NO sur le SSBadgeView. la sous-vue d'image de SSBadgeView est disposée comme prévu mais le parent SSBadgeView de l'image n'est nulle part visible.
topwik

1
Vous avez oublié de désactiver TranslatesAutoresizingMaskIntoConstraints dans vos sous-vues
Softlion

C'est ce qui se passe lorsque je définis cette propriété, drive.google.com/file/d/0BxuYs8WHXCF7bV9ndHFrQ0dMYVE/ ... J'utilise cette ligne de code: [self.contentView setTranslatesAutoresizingMaskIntoConstraints: NO]; for (UIView * vue dans self.contentView.subviews) {[vue setTranslatesAutoresizingMaskIntoConstraints: NO]; } Auparavant, cela ressemblait à: drive.google.com/file/d/0BxuYs8WHXCF7OWlvZGQwN3FlbzQ/ ... Cela fonctionnait cependant, je dois dire.
rptwsthi

28

Veillez à ne pas utiliser plus d'une contrainte dans la même direction et le même type.

Par exemple: Contrainte verticale pour fin = 15 et une autre est> = 10.

Parfois, Xcode crée des contraintes que vous ne remarquez pas . Vous devez vous débarrasser des contraintes redondantes et l'avertissement de journal disparaîtra sûrement.

entrez la description de l'image ici

De plus, vous pouvez lire et détecter certaines raisons, directement à partir du journal :

NSLayoutConstraint: 0xa338390 V: | - (15) - [UILabel: 0xa331260] (Noms: '|': UILabel: 0xa330270)>

Nous pouvons lire cela comme un problème dans la contrainte UILabel, c'est une contrainte verticale de 15pt de long.

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

Ce serait une contrainte horizontale de fin, etc.


6

J'ai eu un certain nombre de ces exceptions lancées, le moyen le plus rapide et le plus simple que j'ai trouvé pour les résoudre était de trouver des valeurs uniques dans les exceptions que j'ai ensuite recherchées dans le code source du storyboard. Cela m'a aidé à trouver la ou les vues et les contraintes réelles à l'origine du problème (j'utilise des userLabels significatifs sur toutes les vues, ce qui facilite le suivi des contraintes et des vues) ...

Donc, en utilisant les exceptions ci-dessus, j'ouvrirais le storyboard en tant que "code source" dans xcode (ou un autre éditeur) et chercherais quelque chose que je peux trouver ...

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

.. cela ressemble à une contrainte verticale (V) sur un UILabel avec une valeur de (17).

En regardant à travers les exceptions, je trouve aussi

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

Ce qui ressemble à l'UILabel (0x72bf7c0) est proche d'un UIButton (0x886efe0) avec un espacement vertical (8).

J'espère que cela me suffira pour trouver les vues spécifiques dans le code source du storyboard (probablement en recherchant dans le texte "17" au départ), ou au moins quelques candidats probables. À partir de là, je devrais être en mesure de déterminer quelles vues se trouvent dans le storyboard, ce qui facilitera grandement l'identification du problème (recherchez les épinglages "dupliqués" ou en conflit avec les contraintes de taille).


"J'utilise des userLabels significatifs" - que sont les userLabels dans ce contexte? (comme comment vous les définissez)
Stripes

Dans la section Document de l'inspecteur d'identité se trouve un champ "Label" .. qui est traduit en une valeur "userLabel" dans le code source du storyboard.
C James

Vous pouvez également les définir en cliquant sur une vue sélectionnée dans le panneau "Vue d'ensemble" de gauche (un peu comme renommer un fichier dans le Finder)
C James

1
Probablement la meilleure chose que j'ai lue en ce qui concerne la résolution du redouté "Incapable de satisfaire simultanément les contraintes". douleur. J'ai trouvé que l'objet montré à ce stade «tentera de récupérer en cassant la contrainte <NSLayoutConstraint:» est généralement le coupable, et comme le dit C James, probablement une contrainte de hauteur ou de largeur qui entre en conflit avec les contraintes d'épinglage. J'ai eu du mal à supprimer la hauteur, mais comme les contraintes étaient correctes, la hauteur pouvait être glanée à partir des autres contraintes. L'ajout d'une contrainte de hauteur vient de confondre la mise en page automatique, c'est donc ce que je recherche maintenant.
latenitecoder le

6

J'ai eu du mal à comprendre quelles contraintes causaient cette erreur. Voici une façon plus simple de le faire.

J'utilise Xcode 6.1.1

  1. "Commande + A" pour sélectionner tous les UILabels, UIImages, etc.
  2. Cliquez sur Editor -> Pin> (Select ...) to Superview
  3. Cliquez à nouveau sur Editeur -> Résoudre les problèmes de disposition automatique -> Ajouter des contraintes manquantes ou Réinitialiser les contraintes suggérées. Cela dépend de votre cas.

5

J'ai eu ce problème car mes .xibfichiers utilisaient la mise en page automatique.

Dans l'inspecteur de fichiers, premier onglet. Le fait de décocher "Utiliser la mise en page automatique" a résolu le problème.

inspecteur de fichiers de mise en page automatique


J'ai donc fait cela et cela a résolu le problème, mais un 'UIImageView' que j'avais en haut de l'écran (que j'ai utilisé comme barre de navigation) a été déplacé vers le bas de l'écran. Savez-vous pourquoi cela s'est produit?
dietbacon

1
La mise en page automatique utilise des contraintes pour régir la disposition des objets. Depuis que vous venez de désactiver la mise en page automatique, ces contraintes ont probablement disparu et la position de votre UIImageViewa donc changé. Vous devez redéfinir cette position, soit par programme, soit via le générateur d'interface.
Stéphane Bruckert

5

Voici mon expérience et ma solution. Je n'ai pas touché au code

  1. Sélectionnez la vue (UILabel, UIImage, etc.)
  2. Editeur> Épingler> (Sélectionner ...) à Superview
  3. Editeur> Résoudre les problèmes de disposition automatique> Ajouter des contraintes manquantes

4

utilisez ce code rapide

view.translatesAutoresizingMaskIntoConstraints = false

1
Ceci est une réponse rapide à une question avec un objectif C.
Tobi Nary

2
@SmokeDispenser Quoi qu'il en soit, j'ai mentionné qu'il s'agissait d'un code rapide. et cela a fonctionné pour moi. swift / objectif, il a un SDK tactile commun.
Arun Kumar P

2

J'ai suivi les questions et réponses SO de chaque requête de recherche. Mais ils sont tous liés à un spécifique.

À la base, je veux dire avant que vous n'écriviez un format (peut-être simple), cela vous donnera des avertissements.

Depuis iOS 8.0, les vues par défaut sont des classes de taille. Même si vous désactivez les classes de taille, il contiendra toujours des contraintes de mise en page automatique.

Donc, si vous prévoyez de définir des contraintes via du code à l'aide de VFL. Ensuite, vous devez vous en occuper d'une ligne ci-dessous.

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

J'ai beaucoup cherché dans SO, mais la solution résidait dans l' exemple de code Apple .

Vous devez donc supprimer les contraintes par défaut avant de prévoir d'en ajouter une nouvelle.


1

Pour moi, la raison principale de ce problème était que j'avais oublié de décocher AutoLayoutdans l' Xibéditeur. En fait, j'ai fait beaucoup d'ajustements XIBdans le code.


1
 for(UIView *view in [self.view subviews]) {
    [view setTranslatesAutoresizingMaskIntoConstraints:NO];
}

Cela m'a aidé à saisir la vue à l'origine du problème.


1

Aucune des réponses ci-dessus n'est utile dans ma situation. J'utilise XCode 10.1 et teste mon application sur le simulateur pour un "iPad (5e génération)". Le simulateur exécute iOS 12.1.

J'ai une vue racine simple dans mon storyboard, avec deux sous-vues UITextField. Il n'y a aucune contrainte utilisée dans le storyboard. Et je n'ai pas d'objets UIButtonBarView dans l'application ou le storyboard.

Aucun message n'est imprimé lorsque l'application se lance et affiche la vue racine. Aucun lorsque l'appareil simulé est tourné.

Mais dans le simulateur, au moment où je clique sur l'un des champs de texte, l'extension du clavier apparaît du bas de l'écran, mais pas le clavier complet, qui ne semble jamais apparaître dans le simulateur. Mais ce qui suit est imprimé sur le terminal:

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.

Il me semble certainement que tout cela n'a à voir avec rien dans mon application, et tout à voir avec la façon dont Apple crée sa propre vue clavier, même avec ma petite extension déclarée être combinée avec elle.

Donc, la question demeure, y a-t-il quelque chose que je suis responsable de faire en tant que développeur d'applications (sur la présomption que c'est un tas de choses qui méritent d'être examinées) ou est-ce juste le propre problème / bogue d'Apple?

FWIW, ce message de problème de contrainte ne se produit pas lors de la simulation d'un modèle d'iPad plus récent, tel que l'iPad Pro 12,9 pouces (3e génération). Mais le message apparaît lors de la simulation d'un iPad Pro 9,7 pouces ". Tous prétendent utiliser iOS 12.1.


1

J'obtiens la même erreur, mais uniquement sur une vue spécifique, lorsque je touche le premier champ de texte, puis le champ de texte suivant vers le bas.

J'écris dans SwiftUI pour 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

J'avais également le même problème de rupture de contraintes dans le journal, pour un viewCircle dans le xib. J'ai presque essayé tout ce qui est énuméré ci-dessus et rien ne fonctionnait pour moi. Ensuite, j'ai essayé de changer la priorité de la contrainte de hauteur qui cassait dans le journal (confirmée en ajoutant un identifiant pour les contraintes sur le xib) entrez la description de l'image ici


-1

Une chose à surveiller (au moins cela m'a fait trébucher) était que je supprimais la contrainte de la mauvaise vue. La contrainte que j'essayais de supprimer n'était pas une contrainte enfant de ma vue, alors quand je l'ai fait

myView.removeConstraint(theConstraint)

il ne supprimait rien parce que j'avais besoin d'appeler

myView.superView.removeConstraint(theConstraint)

puisque la contrainte était techniquement la contrainte fraternelle de mon point de vue.


-4

rapide 4

J'ajoute simplement cette ligne dans viewDidLoad et fonctionne bien avec moi.

view.removeConstraints(view.constraints)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.