IOS 简单的 Visual Format 布局不起作用

Posted

技术标签:

【中文标题】IOS 简单的 Visual Format 布局不起作用【英文标题】:IOS simple Visual Format layout doesn't work 【发布时间】:2016-02-01 11:20:57 【问题描述】:

我正在使用 Objective-C 和 XCode 7 练习可视化格式布局,但很难让一个非常简单的布局工作。 我的应用程序只是一个简单的单视图应用程序,我正在尝试将 UILabel 添加到主视图。 下面是代码。

- (void)viewDidLoad 
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UILabel *label = [[UILabel alloc] init];
    label.text = @"Hello world";
    label.layer.borderWidth = 1.0f;
    label.layer.borderColor = [UIColor redColor].CGColor;

    [self.view addSubview:label];

    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(label);
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"|[label]|"
                                             options:0
                                             metrics:nil views:viewsDictionary]];
    [self.view addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]|"
                                             options:0
                                             metrics:nil views:viewsDictionary]];

    NSLog(@"constraints: %@", self.view.constraints);

运行这个我得到一堆错误:

    2016-02-01 18:14:15.729 AutolayoutVisualFormat[26671:909266] constraints: (
    "<_UILayoutSupportConstraint:0x79771ab0 V:[_UILayoutGuide:0x7976f950(0)]>",
    "<_UILayoutSupportConstraint:0x79786d30 V:|-(0)-[_UILayoutGuide:0x7976f950]   (Names: '|':UIView:0x79771790 )>",
    "<_UILayoutSupportConstraint:0x797884e0 V:[_UILayoutGuide:0x79772e30(0)]>",
    "<_UILayoutSupportConstraint:0x79777540 _UILayoutGuide:0x79772e30.bottom == UIView:0x79771790.bottom>",
    "<NSLayoutConstraint:0x7978d930 H:|-(0)-[UILabel:0x7976d000'Hello world']   (Names: '|':UIView:0x79771790 )>",
    "<NSLayoutConstraint:0x7978da50 H:[UILabel:0x7976d000'Hello world']-(0)-|   (Names: '|':UIView:0x79771790 )>",
    "<NSLayoutConstraint:0x7978fcb0 V:|-(0)-[UILabel:0x7976d000'Hello world']   (Names: '|':UIView:0x79771790 )>",
    "<NSLayoutConstraint:0x7978fce0 V:[UILabel:0x7976d000'Hello world']-(0)-|   (Names: '|':UIView:0x79771790 )>"
)
2016-02-01 18:14:15.733 AutolayoutVisualFormat[26671:909266] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x7a0630a0 h=--& v=--& H:[UILabel:0x7976d000'Hello world'(0)]>",
    "<NSLayoutConstraint:0x7978d930 H:|-(0)-[UILabel:0x7976d000'Hello world']   (Names: '|':UIView:0x79771790 )>",
    "<NSLayoutConstraint:0x7978da50 H:[UILabel:0x7976d000'Hello world']-(0)-|   (Names: '|':UIView:0x79771790 )>",
    "<NSLayoutConstraint:0x7a080130 'UIView-Encapsulated-Layout-Width' H:[UIView:0x79771790(320)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7978da50 H:[UILabel:0x7976d000'Hello world']-(0)-|   (Names: '|':UIView:0x79771790 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2016-02-01 18:14:15.733 AutolayoutVisualFormat[26671:909266] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x7a0758b0 h=--& v=--& V:[UILabel:0x7976d000'Hello world'(0)]>",
    "<NSLayoutConstraint:0x7978fcb0 V:|-(0)-[UILabel:0x7976d000'Hello world']   (Names: '|':UIView:0x79771790 )>",
    "<NSLayoutConstraint:0x7978fce0 V:[UILabel:0x7976d000'Hello world']-(0)-|   (Names: '|':UIView:0x79771790 )>",
    "<NSLayoutConstraint:0x7a081610 'UIView-Encapsulated-Layout-Height' V:[UIView:0x79771790(568)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7978fce0 V:[UILabel:0x7976d000'Hello world']-(0)-|   (Names: '|':UIView:0x79771790 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

【问题讨论】:

您没有提供标签框架。所以它不会显示在任何地方。 【参考方案1】: 添加这一行就可以了

[label setTranslatesAutoresizingMaskIntoConstraints:NO];

在代码中创建的视图上使用自动布局时,有一些 需要注意的警告。第一个与价值有关 财产translatesAutoresizingMaskIntoConstraints。该物业是 默认为 YES,这意味着将创建 Auto Layout 约束 基于视图的自动调整大小掩码。我们希望尊重的观点 我们将添加的自动布局约束,所以这个属性应该是 设置为 NO。 这是早期用于管理视图大小的旧技术 你可以参考这个链接UIView autoresizingMask - Interface Builder to Code - Programmatically create struts and springs - Swift or Objective-C
当此属性为 YES(默认情况下)时,视图的自动调整大小掩码将转换为约束。例如,如果一个视图 配置如图 6-1 和 translatesAutoresizingMaskIntoConstraints 为 YES,则 约束 |-20-[按钮]-20-|和 V:|-20-[button(20)] 被添加到 视图的超级视图。最终效果是不知情的视图表现得像 他们在 10.7 之前的 OS X 版本中做到了。 对于知道自动布局的视图,在大多数情况下,您会希望 translatesAutoresizingMaskIntoConstraints 为 NO。 这是因为翻译产生的约束 自动调整大小掩码已经足以完全指定 给定其父视图的框架的视图的框架,通常也是 很多。例如,这将阻止按钮自动 假设其标题更改时的最佳宽度。

【讨论】:

谢谢,添加解决了我的问题。你能解释一下自动调整蒙版吗?我也从 Apple 文档中看到它,但不确定它是关于什么的。 感谢 Yaiba 很高兴为您提供帮助。 我还不能投票,但是 +1 添加关于自动调整掩码 (y) 的解释

以上是关于IOS 简单的 Visual Format 布局不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用Auto Layout中的VFL(Visual format language)--代码实现自动布局转

Visual Studio的工程结构解析

iOS / XCode 自动布局问题。更简单的方法?

Visual Format Language

可变宽度标签列的 iOS 自动布局

Xamarin iOS:无法对Visual Studio 2017中的控件设置约束