web-dev-qa-db-fra.com

Mise en page automatique, impossible de satisfaire simultanément les contraintes

Je viens de commencer à apprendre iOS AutoLayout, le générateur d'interface très simple, mais quand j'essaie d'archiver la même chose sur le code

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(==2)-[_nextKeyboardButton]-(==2)-[_numPadButton]-(==2)-[_spaceButton]-(==2)-[_returnButton]-(==2)-|" options:0 metrics:0 views:NSDictionaryOfVariableBindings(_nextKeyboardButton,_numPadButton,_spaceButton,_returnButton)]];

cela soulève une exception,

Impossible de satisfaire simultanément les contraintes.

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:0x6000000966c0 H:|-(2)-[UIButton:0x7fe4f1d1c760'Next']   (Names: '|':UIInputView:0x7fe4f1f04d00 )>",
 "<NSLayoutConstraint:0x600000096710 H:[UIButton:0x7fe4f1d1c760'Next']-(2)-[UIButton:0x7fe4f1d1d1d0'123']>",
 "<NSLayoutConstraint:0x600000096760 H:[UIButton:0x7fe4f1d1d1d0'123']-(2)-[UIButton:0x7fe4f1d1d6f0'Space']>",
 "<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']>",
 "<NSLayoutConstraint:0x600000096800 H:[UIButton:0x7fe4f1d1d8d0'Return']-(2)-|   (Names: '|':UIInputView:0x7fe4f1f04d00 )>",
 "<NSLayoutConstraint:0x600000096e40 'UIView-Encapsulated-Layout-Width' H:[UIInputView:0x7fe4f1f04d00(0)]>"
 )

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x6000000967b0 H:[UIButton:0x7fe4f1d1d6f0'Space']-(2)-[UIButton:0x7fe4f1d1d8d0'Return']>

Les 4 boutons .translatesAutoresizingMaskIntoConstraints = NO;

Je me demande ce qui ne va pas? l'aide est vraiment appréciée :)

Pour info: je travaille sur le SDK iOS8

30
Chamira Fernando

La manière la plus simple de trouver des contraintes insatisfaisantes:

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

enter image description here

  • créer une extension simple pour NSLayoutConstraint:

Rapide :

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:

enter image description here

  • une fois que vous avez obtenu votre id, vous pouvez simplement le toucher dans votre Find Navigator :

enter image description here

  • et le trouver rapidement:

enter image description here

COMMENT RÉGLER SIMPLEMENT CE CAS?

  • essayez de changer la priorité en 999 pour une contrainte brisée.

Voir la réponse connexe ici: Impossible de satisfaire simultanément les contraintes, tentera de récupérer en cassant la contrainte

80

J'ai dû lutter avec un problème similaire lorsque j'essayais de créer manuellement toutes les contraintes de mise en page automatique (dans Swift, en utilisant Snappy - un port de maçonnerie vers Swift) dans un contrôleur de vue basé sur un Storyboard.

Pour une raison quelconque, Xcode génère son propre ensemble par défaut de contraintes de mise en page automatique sur une NIB au moment de la construction. C'est pourquoi je n'ai pas pu ajouter de contraintes manuelles supplémentaires, car elles étaient en conflit avec celles ajoutées automatiquement.

J'ai résolu cela de la manière suivante:

  • Ouvrez le contrôleur de vue Storyboard que vous gérez.

  • Sélectionnez le contrôleur de vue et sélectionnez Editeur> Résoudre les problèmes de disposition automatique> Toutes les vues dans [] Contrôleur de vue> Ajouter des contraintes manquantes dans le menu:

enter image description here

(Cela garantira qu'aucune contrainte de temps de génération supplémentaire n'est créée et que toutes les contraintes sont désormais visibles.)

  • Sélectionnez toutes les contraintes de votre contrôleur de vue:

enter image description here

  • Cochez dans le volet droit la case à cocher suivante: Placeholder - Remove at build time:

enter image description here

Vous pouvez maintenant ajouter manuellement toutes les contraintes de disposition automatique dans le code.

8
Markus Rautopuro

Dans le cas où quelqu'un d'autre se heurterait à cela, un site facile pour vérifier visuellement les problèmes avec vos contraintes est ce site (c'est vraiment utile!):

http://www.wtfautolayout.com

Voici le projet Github en cas de panne du site: https://github.com/johnpatrickmorgan/wtfautolayout

3
JoniVR

Ce n'est peut-être pas si difficile. La sortie de la console de message indique que les contraintes de l'UIButton ont été redéfinies. Cela signifie tout comme vous mettez une contrainte qui restreint le Height et le Width du bouton, mais inutilement vous mettez une autre restriction que le bouton a un Aspect Ratio. Dans cette condition, Xcode ne peut pas déterminer la contrainte à suivre, afin que vous puissiez voir ce message de débogage dans la console.

Il y a deux façons utiles pour moi:

  1. Analysez les contraintes affichées dans la console et essayez de supprimer une ou plusieurs contraintes.

2.Si vous utilisez storyboard ou Xib, sélectionnez une contrainte -> Afficher l'inspecteur des attributs -> modifiez la priorité de certaines contraintes.


Encore une chose ...

Vous pouvez suivre le article de Jason Jarrett. Ajoutez un point d'arrêt de symbole pour vous assurer de la vue à l'origine de l'erreur.

3
lynulzy

Selon votre question, ce que j'ai compris, c'est que vous avez créé un contrôle dans nib et que vous essayez directement de changer les contraintes de votre classe.

Ce que vous pouvez faire ici est de définir des contraintes dans nib pour le contrôleur de vue, puis de le lier à votre classe et d'utiliser des objets de contraintes. Ou vous pouvez créer une vue par programme et définir directement les contraintes.

// Vous devez également vérifier si vous devez "translatesAutoresizingMaskIntoConstraints" si "OUI - la vue d'ensemble de la vue examine le masque de redimensionnement automatique de la vue, produit des contraintes qui l'implémentent et ajoute ces contraintes à elle-même (la vue d'ensemble)." Et si " NON - la vue d'ensemble de la vue ne regarde pas le masque de redimensionnement automatique de la vue et ne produit pas de contraintes qui l'implémentent. "

J'ai également eu le même problème et je l'ai résolu comme suit

     [_nextKeyboardButton setTranslatesAutoresizingMaskIntoConstraints:YES];
    _numPadButton.translatesAutoresizingMaskIntoConstraints = YES;
    [_numPadButton updateConstraints];
    [_nextKeyboardButton updateConstraints];

    NSArray *constraints2 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"H:|-57-[_nextKeyboardButton(96)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_nextKeyboardButton)];

    [self.view addConstraints:constraints2];

    NSArray *constraints4 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"V:|-123-[_nextKeyboardButton(30)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_nextKeyboardButton)];

    [self.view addConstraints:constraints4];

    NSArray *constraints1 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"H:|-207-[_numPadButton(58)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_numPadButton)];

    [self.view addConstraints:constraints1];

    NSArray *constraints3 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"V:|-123-[_numPadButton(30)]"
                             options:0
                             metrics:nil
                             views:NSDictionaryOfVariableBindings(_numPadButton)];

    [self.view addConstraints:constraints3];

// Create Controls  or view programmatically.

UILabel *label = [UILabel new];
    label.text = @"This is a Label";
    label.font = [UIFont systemFontOfSize:18];
    label.backgroundColor = [UIColor lightGrayColor];
    label.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:label];

    NSArray *constraints = [NSLayoutConstraint
                            constraintsWithVisualFormat:@"V:|-offsetTop-[label(100)]"
                            options:0
                            metrics:@{@"offsetTop": @100}
                            views:NSDictionaryOfVariableBindings(label)];
    [self.view addConstraints:constraints];

    UIView *spacer1 = [UIView new];
    spacer1.translatesAutoresizingMaskIntoConstraints = NO;
    [spacer1 setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:spacer1];

    UIView *spacer2 = [UIView new];
    spacer2.translatesAutoresizingMaskIntoConstraints = NO;
    [spacer2 setBackgroundColor:[UIColor greenColor]];
    [self.view addSubview:spacer2];

    NSArray *constraints1 = [NSLayoutConstraint
                            constraintsWithVisualFormat:@"V:|-offsetTop-[spacer1(100)]"
                            options:0
                            metrics:@{@"offsetTop": @100}
                            views:NSDictionaryOfVariableBindings(spacer1)];

    [self.view addConstraints:constraints1];

    NSArray *constraints2 = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"V:|-offsetTop-[spacer2(100)]"
                             options:0
                             metrics:@{@"offsetTop": @100}
                             views:NSDictionaryOfVariableBindings(spacer2)];

    [self.view addConstraints:constraints2];

    [self.view addConstraints:[NSLayoutConstraint
                               constraintsWithVisualFormat:@"H:|[spacer1]-10-[label]-20-[spacer2(==spacer1)]|"
                               options:0
                               metrics:nil
                               views:NSDictionaryOfVariableBindings(label, spacer1, spacer2)]];

Ainsi, lorsque vous utilisez la mise en page automatique, vous ne devez jamais définir directement le cadre d'une vue. Les contraintes sont utilisées pour cela pour vous. Normalement, si vous souhaitez définir vos propres contraintes dans une vue, vous devez remplacer la méthode updateConstraints de vos UIViews. Assurez-vous que les vues de contenu du contrôleur de page permettent de redimensionner leurs bords, car ils seront dimensionnés pour s'adapter au cadre de la vue de page. Vos contraintes et la configuration de la vue devront en tenir compte, sinon vous obtiendrez des erreurs de contrainte non satisfaisantes.

https://developer.Apple.com/library/mac/documentation/userexperience/conceptual/AutolayoutPG/AutoLayoutConcepts/AutoLayoutConcepts.html#//Apple_ref/doc/uid/TP40010853-CH14-SW1 Vous pouvez reportez-vous également au lien ci-dessus de Apple pour une étude approfondie et si vous rencontrez toujours un problème, je ferai de mon mieux pour résoudre votre problème.

2
user821127