'NSInvalidArgumentException',原因:'无法parsing约束格式'

我有一个子视图,我想在旋转屏幕期间保持停止,所以我决定把NSLayoutConstrainttypes:

尾随空间来监视
顶层空间到Superview
button空间Superview
我在UITableViewCell的子类中。 我写了代码,但我得到以下错误:

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

我在CustomCell.m中的代码是:

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

它看起来像自动布局可视化格式分析引擎正在解释VFL约束中的“ . ”是一个keyPath,而不是像使用valueForKeyPath:的键。

NSDictionaryOfVariableBindings(...)将采取括号中的任何参数,并将其转换为一个字面值的对象作为值(在您的情况: @{"self.arrow" : self.arrow} )。 在VFL的情况下,自动布局认为你的视图字典中有一个名为self的键,其子键(或子对象)有一个arrow

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

当你真的希望系统把你的密钥解释为“ self.arrow ”。

通常,当我使用像这样的实例variablesgetter时,我通常最终创build自己的字典,而不是像这样使用NSDictionaryOfVariableBindings(...)

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

要么

 NSDictionary *views = NSDictionaryOfVariableBindings(_arrow); 

这将允许你在没有自己的情况下使用VFL中的视图,而且你仍然知道你在说什么:

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

要么

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

作为一般规则,我已经学会了不在字典中使用点( . )来避免任何系统混淆或debugging噩梦。

我的窍门是简单地声明一个局部variables,这只是另一个指向属性的指针,并将其放在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); 

P后缀是“指针”。

最简单的解决scheme是避免从你自己的类中获取variables的getter,并将超类的variables重新定义为局部variables。 你的例子的解决scheme是

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

确保在将主要视图添加到所需的子视图后添加约束。花了一段时间才得到有关此问题的知识。