'NSInvalidArgumentException', reason: 'Unable to parse constraint format'

IosLayoutCompiler ErrorsConstraintsAutolayout

Ios Problem Overview


I have a subview that I want to keep stops during rotating screen, so I decided to put the NSLayoutConstraint type:

Trailing Space to Superview
Top Space to Superview
Button Space to Superview
I'm in a subclass of UITableViewCell. I wrote the code but I get the following error:

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


My code in CustomCell.m is:

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

Ios Solutions


Solution 1 - Ios

It looks like that the autolayout visual format parsing engine is interpreting the "." in your VFL constraint to be a keyPath instead of a key like it's using valueForKeyPath:.

NSDictionaryOfVariableBindings(...) will take whatever your parameter is in the parenthesis and translate it into a literal key with the object as the value (in your case: @{"self.arrow" : self.arrow}). In the case of the VFL, autolayout is thinking that you have a key named self in your view dictionary with a subdictionary (or subobject) that has a key of arrow,

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

when you literally wanted the system to interpret your key as "self.arrow".

Usually, when I'm using a instance variables getter like this, I typically end up creating my own dictionary instead of using NSDictionaryOfVariableBindings(...) like so:

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

or

NSDictionary *views = NSDictionaryOfVariableBindings(_arrow);

Which would allow you to use the view in your VFL without the self and you still know what you're talking about:

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

or

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

As a general rule, I've learned not to have dictionary keys with a dot (.) in them to avoid any system confusion or debugging nightmares.

Solution 2 - Ios

My trick is to simply declare a local variable that's just another pointer to the property, and put it in the 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);

The P suffix is for "pointer".

Solution 3 - Ios

Easiest solution is to avoid the getters for variables from your own class and redefine variables from superclasses as local variables. A solution for your example is

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

Solution 4 - Ios

Make sure you add the constraints after adding the required subview to your main view.It took a while get knowledge relating to this issue .

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1747321View Question on Stackoverflow
Solution 1 - IoslarsacusView Answer on Stackoverflow
Solution 2 - IosEricView Answer on Stackoverflow
Solution 3 - IosMihai DamianView Answer on Stackoverflow
Solution 4 - IosNassifView Answer on Stackoverflow