'NSInvalidArgumentException', razón: 'No se puede analizar el formatting de restricción'

Tengo una subvista que quiero mantener detenida durante la rotation de la pantalla, así que decidí poner el tipo NSLayoutConstraint:

Espacio posterior a Superview
Espacio superior a Superview
Espacio del button para supervisar
Estoy en una subclass de UITableViewCell. Escribí el código pero obtuve el siguiente error:

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

Mi código en CustomCell.m es:

  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]; 

Parece que el motor de análisis de formatting visual de autolayout está interpretando el " . " En su restricción de VFL para ser un KeyPath en lugar de una key como la que usa valueForKeyPath:

NSDictionaryOfVariableBindings(...) tomará cualquiera que sea su parámetro entre paréntesis y lo traduzca a una key literal con el object como valor (en su caso: @{"self.arrow" : self.arrow} ). En el caso del VFL, autolayout está pensando que tiene una key llamada self en su dictionary de vista con un subdictionary (o subobject) que tiene una tecla de arrow ,

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

cuando literalmente quería que el sistema interpretara su key como " self.arrow ".

Por lo general, cuando estoy usando un getter de variables de instancia como este, suelo terminar creando mi propio dictionary en lugar de utilizar NSDictionaryOfVariableBindings(...) así:

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

o

 NSDictionary *views = NSDictionaryOfVariableBindings(_arrow); 

Lo que le permitiría usar la vista en su VFL sin él y todavía sabe de lo que está hablando:

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

o

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

Como regla general, he aprendido a no tener keys de dictionary con un punto ( . ) En ellas para evitar cualquier confusión del sistema o debugging de pesadillas.

Mi truco es simplemente declarar una variable local que es solo otro puntero a la propiedad, y ponerlo en el 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); 

El sufijo P es para "puntero".

La solución más fácil es evitar los getters para las variables de su propia class y networkingefinir las variables de superclasss como variables locales. Una solución para su ejemplo es

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

Asegúrese de agregar las restricciones después de agregar la subvista requerida a su vista principal. Le tomó un time get conocimiento relacionado con este problema.