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

50 layout compiler-errors constraints ios autolayout

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

尾随空间到Superview
顶部空间到Superview
按钮空间到Superview
我在UITableViewCell的子类中.我写了代码,但是我收到以下错误:

'NSInvalidArgumentException', reason: 'Unable to parse constraint format: 
 self is not a key in the views dictionary. 
 H:[self.arrows]-5-|
Run Code Online (Sandbox Code Playgroud)


我在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];
Run Code Online (Sandbox Code Playgroud)

lar*_*cus 121

看起来autolayout可视格式解析引擎.将VFL约束中的" " 解释为keyPath而不是像它正在使用的键valueForKeyPath:.

NSDictionaryOfVariableBindings(...)将取括号中的任何参数并将其转换为文本键,并将对象作为值(在您的情况下:) @{"self.arrow" : self.arrow}.在VFL的情况下,autolayout认为你有一个self在你的视图字典中命名的键,其子字符(或子对象)具有键arrow,

@{
   @"self" : @{ @"arrow" : self.arrow }
}
Run Code Online (Sandbox Code Playgroud)

当你真的希望系统将你的密钥解释为" self.arrow"时.

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

NSDictionary *views = @{ @"arrowView" : self.arrow }
Run Code Online (Sandbox Code Playgroud)

要么

NSDictionary *views = NSDictionaryOfVariableBindings(_arrow);
Run Code Online (Sandbox Code Playgroud)

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

NSArray *arrowHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[arrowView]-5-|" options:0 metrics:nil views];
Run Code Online (Sandbox Code Playgroud)

要么

NSArray *arrowHorizConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[_arrow]-5-|" options:0 metrics:nil views];
Run Code Online (Sandbox Code Playgroud)

作为一般规则,我已经学会了不要在其中包含带点(.)的字典键,以避免任何系统混乱或调试噩梦.

  • 非常荒谬的是,文档提供了使用`NSDictionaryOfVariableBindings`创建字典的示例,但没有提到它不适用于任何属性或IBOutlets (25认同)
  • "非常荒谬"是......本周的轻描淡写. (5认同)

Eri*_*ric 7

我的诀窍是简单地声明一个局部变量,它只是另一个指向该属性的指针,并将其放入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);
Run Code Online (Sandbox Code Playgroud)

P后缀是"指针".

  • 这否定了NSDictionaryOfVariableBindings的观点,即缩短范围.为什么不使用`NSDictionary*views = @ {@"myButton":self.myButton,@"myLabel":self.myLabel}`而不是?它更短. (2认同)