50 votes

NSInvalidArgumentException", reason : "Unable to parse constraint format" (Impossible d'analyser le format de la contrainte)

J'ai une sous-vue que je veux garder arrêtée pendant la rotation de l'écran, j'ai donc décidé d'utiliser le type NSLayoutConstraint :

Espace à la fin de la vue d'ensemble
Top Space pour Superview
Bouton Espace à Supervision
Je suis dans une sous-classe de UITableViewCell. J'ai écrit le code mais j'obtiens l'erreur suivante :

'NSInvalidArgumentException', reason: 'Unable to parse constraint format: 
 self is not a key in the views dictionary. 
 H:[self.arrows]-5-|

Mon code dans CustomCell.m est le suivant :

 self.arrows = [[Arrows alloc]initWithFrame:CGRectMake(self.contentView.bounds.size.width-30, self.bounds.origin.y+4, 30, self.contentView.bounds.size.height-4)];

 NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(self.arrows, self.contentView);
 NSMutableArray * constraint=[[NSMutableArray alloc]init];
 [constraint addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:  [self.arrows]-5-|" options:0 metrics:nil views:viewsDictionary]];
 [constraint addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-1-[self.arrows]" options:0 metrics:nil views:viewsDictionary]];
 [constraint addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"[V: [self.arrows]-1-|" options:0 metrics:nil views:viewsDictionary]];
 [self.arrows addConstraints:constraint];

121voto

larsacus Points 4024

Il semble que la mise en page automatique format visuel moteur d'analyse est de l'interprétation de la "." dans votre VFL contrainte à être un chemin d'accès clé au lieu d'une clé, comme c'est à l'aide de valueForKeyPath:.

NSDictionaryOfVariableBindings(...) va prendre que votre paramètre est dans la parenthèse et de les traduire dans un littéral de la clé avec l'objet en tant que valeur (dans votre cas: @{"self.arrow" : self.arrow}). Dans le cas de la VFL, mise en page automatique est de penser que vous avez une clé nommée self , à votre avis, dictionnaire avec un subdictionary (ou sous-objet) qui a une clé de arrow,

@{ @"self" : @{ @"arrow" : self.arrow } }

lorsque vous voulu littéralement le système pour interpréter votre clé comme "self.arrow".

Habituellement, quand je suis à l'aide d'une des variables d'instance de lecture de ce genre, je finissent généralement par la création de mon propre dictionnaire au lieu d'utiliser NSDictionaryOfVariableBindings(...) comme:

NSDictionary *views = @{ @"arrowView" : self.arrow }

ou

NSDictionary *views = NSDictionaryOfVariableBindings(_arrow);

Ce qui vous permettrait d'utiliser la vue dans votre VFL sans l'auto et que vous savez de quoi vous parlez:

NSArray *arrowHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[arrowView]-5-|" options:0 metrics:nil views];

ou

NSArray *arrowHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[_arrow]-5-|" options:0 metrics:nil views];

En règle générale, j'ai appris à ne pas avoir les clés de dictionnaire avec un point (.) afin d'éviter tout système de confusion ou de débogage des cauchemars.

7voto

Eric Points 1892

Mon astuce consiste à déclarer une variable locale qui n'est autre qu'un pointeur sur la propriété, et à la placer dans le fichier NSDictionaryOfVariableBindings .

@interface ViewController ()
@property (strong) UIButton *myButton;
@property (strong) UILabel *myLabel;
@end

...

UIButton *myButtonP = self.myButton;
UILabel *theLabelP = self.myLabel;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(myButtonP, myLabelP);

En P signifie "pointeur".

1voto

Mihai Damian Points 3714

La solution la plus simple est d'éviter les getters pour les variables de votre propre classe et de redéfinir les variables des superclasses comme des variables locales. Une solution pour votre exemple est la suivante

UIView *contentView = self.contentView;
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(_arrows, contentView);

-1voto

Nassif Points 140

Assurez-vous d'ajouter les contraintes après avoir ajouté la vue secondaire requise à votre vue principale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X