设置视觉格式语言时 iAutoLayout 崩溃

Posted

技术标签:

【中文标题】设置视觉格式语言时 iAutoLayout 崩溃【英文标题】:iAutoLayout crash when setting Visual Format Language 【发布时间】:2015-01-13 13:01:03 【问题描述】:

您好,我正在使用带有视觉格式语言的 autoLayouts 设置我的视图。

我在视图中添加了一些约束。

这是我如何设置的代码:

- (void)viewDidLoad

self.first  = [UIView new];
self.second = [UIView new];
self.third  = [UIView new];
self.fourth = [UIView new];
self.fifth  = [UIView new];

self.first.translatesAutoresizingMaskIntoConstraints  = NO;
self.second.translatesAutoresizingMaskIntoConstraints = NO;
self.third.translatesAutoresizingMaskIntoConstraints  = NO;
self.fourth.translatesAutoresizingMaskIntoConstraints = NO;
self.fifth.translatesAutoresizingMaskIntoConstraints  = NO;

[self.view addSubview:self.first];
[self.view addSubview:self.second];
[self.view addSubview:self.third];
[self.view addSubview:self.fourth];
[self.view addSubview:self.fifth];

NSDictionary *dictionary = NSDictionaryOfVariableBindings(_first, _second, _third, _fourth, _fifth);

NSArray *constraintsArray;
NSString *format;

format = @"|[_first][_second][_third][_fourth][_fifth]|";
constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:NSLayoutFormatAlignAllLeft metrics:nil views:dictionary];
[self.view addConstraints:constraintsArray];

format = @"V:|[_first]|";
constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:NSLayoutFormatAlignAllLeft metrics:nil views:dictionary];
[self.view addConstraints:constraintsArray];

format = @"V:|[_second]|";
constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:NSLayoutFormatAlignAllLeft metrics:nil views:dictionary];
[self.view addConstraints:constraintsArray];

format = @"V:|[_third]|";
constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:NSLayoutFormatAlignAllLeft metrics:nil views:dictionary];
[self.view addConstraints:constraintsArray];

format = @"V:|[_fourth]|";
constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:NSLayoutFormatAlignAllLeft metrics:nil views:dictionary];
[self.view addConstraints:constraintsArray];

format = @"V:|[_fifth]|";
constraintsArray = [NSLayoutConstraint constraintsWithVisualFormat:format options:NSLayoutFormatAlignAllLeft metrics:nil views:dictionary];
[self.view addConstraints:constraintsArray];


这就是我希望五个UIViews 扮演的角色。它们具有相同的 WIDTH 和 HEIGHT,并且两种尺寸都有 无边距。(第一个和最后一个)。也就是说,它们填充在容器视图中,在这种情况下,(self.view)

当我运行时,应用程序崩溃:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse   constraint format: 
Options mask required views to be aligned on a horizontal edge, which is not allowed for layout that is also horizontal. 
|[_first][_second][_third][_fourth][_fifth]| 
                  ^'

我做错了什么? 请帮我。谢谢。

【问题讨论】:

【参考方案1】:

您应该删除所有对NSLayoutFormatAlignAllLeft 的引用。

另外,不相关,但是您缺少使它们具有相同宽度的约束。我会将水平约束替换为:

format = @"H:|[_first][_second(==_first)][_third(==_first)][_fourth(==_first)][_fifth(==_first)]|";

【讨论】:

谢谢 Rob,NSLayoutFormatAlignAllLeft 应该替换为什么?你的意思是零? kNilOptions 不起作用 Rob,您在哪里找到该常量以及它应该设置为什么? 在 Objective-C 中,kNilOptions 是一个标准常量,用于 Cocoa API 中接受多个选项的情况。但我从您的问题中猜测您正在使用 Swift,在这种情况下,您现在在 Swift 2 及更高版本中使用 []【参考方案2】:

Rob 提出的格式字符串是完美的。您还可以避免所有其他垂直约束,只需添加“NSLayoutFormatAlignAllTop”而不是“NSLayoutFormatAlignAllLeft”。 基本上,当您处理与水平轴相关的格式字符串时,您必须使用与垂直轴相关的对齐选项,反之亦然(选项垂直于格式字符串),或者如果您不需要它,只需传递 0。 您唯一的一种方法应如下所示:

NSString format = @"H:|[_first][_second(==_first)][_third(==_first)][_fourth(==_first)][_fifth(==_first)]|";

[NSLayoutConstraint constraintsWithVisualFormat:format 
                                        options:NSLayoutFormatAlignAllTop
                                        metrics:nil
                                          views:dictionary];

[编辑]

罗伯是对的。 NSLayoutFormatAlignAllTop 将视图的所有顶部对齐在它们之间的格式字符串内,而不是与它们的父视图对齐。您必须将一个垂直引脚约束添加到您的一个视图中,并且所有其他视图也会因为“NSLayoutFormatAlignAllTop”而对齐。此外,要删除不明确的布局,您需要添加高度约束。这是我尝试过的代码(高度为 100 点)并且没有给我模棱两可的布局:

NSDictionary *dictionary = NSDictionaryOfVariableBindings(_first, _second, _third, _fourth, _fifth);


NSString *format = @"H:|[_first][_second(==_first)][_third(==_first)][_fourth(==_first)][_fifth(==_first)]|";

NSMutableArray *constraintsArray =  [NSLayoutConstraint constraintsWithVisualFormat:format
                                                                           options:NSLayoutFormatAlignAllTop
                                                                           metrics:nil
                                                                             views:dictionary].mutableCopy;

[constraintsArray addObject:[NSLayoutConstraint constraintWithItem:_first
                                                         attribute:NSLayoutAttributeTop
                                                         relatedBy:NSLayoutRelationEqual
                                                            toItem:_first.superview
                                                         attribute:NSLayoutAttributeTop
                                                        multiplier:1.0 constant:0]];

CGFloat height = 100;

for (UIView *view in @[_first,_second,_third,_fourth,_fifth]) 
    [constraintsArray addObject:[NSLayoutConstraint constraintWithItem:view
                                                             attribute:NSLayoutAttributeHeight
                                                             relatedBy:NSLayoutRelationEqual
                                                                toItem:nil
                                                             attribute:NSLayoutAttributeNotAnAttribute
                                                            multiplier:1.0
                                                              constant:height]];





[self.view addConstraints:constraintsArray];

【讨论】:

也就是说,如果我使用NSLayoutFormatAlignAllTop,我不需要为每个垂直设置约束? 在这个具体的例子中是的,你可以删除所有其他方法,因为这个选项说将所有视图对齐到顶部。 感谢您的建议,Cesare,我会改进我的代码。:) 如果你想掌握代码中的自动布局,我建议你阅读 Erica Sadun 的“Autolayout demystified”。这是一本关于这个主题的好书 @Wong 我不认为你不能摆脱垂直约束,因为你仍然需要设置底部约束。最重要的是,尝试一下,然后运行应用程序,暂停执行,然后在(lldb) 提示符下输入po [[UIWindow keyWindow] _autolayoutTrace]。这将告诉您您的约束是否模棱两可。

以上是关于设置视觉格式语言时 iAutoLayout 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

视觉格式化语言、按钮宽度和高度约束

调用OpenGL函数时程序崩溃

不能满足约束 - 视觉格式语言

使用视觉格式语言约束 2 个视图

OCR 应用程序崩溃并给出错误:jni_helper.cc:110 位图格式错误:4

R语言使用colorblinr包模拟色盲视觉将已有的ggplot2可视化结果图像使用edit_colors函数编辑转化为色盲视觉友好的可视化结果并自定设置色盲形式色盲严重级别