将NSDictionary UIView对象传递给NSDictionaryOfVariableBindings / Autolayout

时间:2014-05-14 16:16:02

标签: objective-c autolayout

如果我将UIView分配给NSDictionary,然后在设置约束时尝试在autolayout中调用它的值

UILabel *label = [[UILabel alloc] init];
NSDictionary *items = [[NSMutableDictionary alloc] init];
[items setValue:label forKey:@"label"];

[NSLayoutConstraint constraintsWithVisualFormat:@"|-[label]-|"
                                   options:0
                                   metrics:nil
                                   views:NSDictionaryOfVariableBindings(
                                      [items objectForKey:@"label"]
                                    )];

我收到以下错误

uncaught exception 'NSInternalInconsistencyException', reason: 'NSDictionaryOfVariableBindings failed because either one of the values is nil, or there's something wrong with the way the macro is being invoked.  Cannot assign value nil for key "objectForKey:@"label"]". Keys:(
"[items",
"objectForKey:@\"label\"]")'

如果我尝试在

中传递数组objectAtIndex:元素,我会得到相同的结果

如果我像这样定义

,它确实有效
[items setValue:NSDictionaryOfVariableBindings(label) forKey:@"label"];

但是我试图将我的UIViews加载到一个集合对象(任何集合对象)中,然后在设置约束时能够调用它们

好像NSDictionaryOfVariableBindings正在解释我传递的文字文本而不是评估语句

1 个答案:

答案 0 :(得分:3)

  

好像NSDictionaryOfVariableBindings正在解释   文字文本我通过而不是评估声明

这正是发生的事情。如果您按住NSDictionaryOfVariableBindings命令,您将看到它的定义为在NSLayoutConstraint.h中调用私有(ish)UIKit函数的宏:

#define NSDictionaryOfVariableBindings(...) _NSDictionaryOfVariableBindings(@"" # __VA_ARGS__, __VA_ARGS__, nil)
UIKIT_EXTERN NSDictionary *_NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, id firstValue, ...) NS_AVAILABLE_IOS(6_0); // not for direct use

宏定义中的@"" # __VA_ARGS__将传递的参数列表转换为文字字符串,该字符串作为commaSeparatedKeysString参数传递给_NSDictionaryOfVariableBindings函数。

使用NSDictionaryOfVariableBindings的正确方法是使用本地范围的变量,或_ - 前缀的ivars(如果适用)。如果您不想这样做,您可以随时使用您想要的任何文字字符串以及您想要的任何值作为值来创建自己的字典。我经常这样做,将我的变量重命名为可视格式语言字符串的有意义的东西。所以,在你的例子中:

UILabel *label = [[UILabel alloc] init];
NSMutableDictionary *items = [[NSMutableDictionary alloc] init];
[items setValue:label forKey:@"label"];

[NSLayoutConstraint constraintsWithVisualFormat:@"|-[label]-|"
                                   options:0
                                   metrics:nil
                                   // using Obj-C dictionary subscripting syntax
                                   views:@{ @"label" : items[@"label"] }];

您的示例可能会受到干扰,但如果不是,UILabel *label在范围内的事实意味着您可以通过NSDictionaryOfVariableBindings(label)传递views:参数。

修改:您的items可变字典已经正确设置,只需传入views:参数即可。