不明确的布局 - 我需要为两个并排视图添加哪些额外的约束?

Posted

技术标签:

【中文标题】不明确的布局 - 我需要为两个并排视图添加哪些额外的约束?【英文标题】:Ambiguous Layout - What Additional Constraint(s) Do I Need to Add for Two Side by Side Views? 【发布时间】:2014-08-28 06:12:21 【问题描述】:

我有一个从导航栏向下滑动的视图 - 允许用户更改标题名称。我正在以编程方式使用自动布局。

我的目标:标签根据需要占用尽可能多的水平空间(例如由于本地化而发生的变化),并且它固定在其超级视图的左侧(有边距)。文本字段占据了其余的空间,无论其内容如何(并且在它和标签之间有一个边距,右边有一个边距)。

问题UILabelUITextField 的布局不明确。除非我的约束完全错误,否则我需要添加额外的约束......我只是不确定要添加什么。我在水平访问上尝试了setContentCompressionResistancePrioritysetContentHuggingPriority,但还没有成功。

我错过了什么?

根据下面的代码,以下图像没有拥抱压缩优先级。

它的外观始终如一:

编辑短名称可能会导致:

编辑长名称可能会导致:

代码如下:

_renameView = [UIView new];
_renameView.translatesAutoresizingMaskIntoConstraints = NO;
_renameView.backgroundColor = _styles.navbarLightGreyTrans;
[self.view addSubview:_renameView];

_renameTextField = [UITextField new];
_renameTextField.translatesAutoresizingMaskIntoConstraints = NO;
_renameTextField.delegate = self;
_renameTextField.clipsToBounds = YES;
_renameTextField.backgroundColor = [UIColor whiteColor];
_renameTextField.layer.cornerRadius = 4.0f;
_renameTextField.layer.borderWidth = 0.7f;
_renameTextField.layer.borderColor = [_styles.greyBorder CGColor];
_renameTextField.font = [UIFont systemFontOfSize:16.0f];
[_renameTextField setReturnKeyType:UIReturnKeyDone];
[_renameView addSubview:_renameTextField];

UIView* separator = [UIView new];
separator.translatesAutoresizingMaskIntoConstraints = NO;
separator.backgroundColor = _styles.greyBorder;
[_renameView addSubview:separator];

UILabel* label = [UILabel new];
label.text = @"Name:";
label.font = [UIFont systemFontOfSize:16.0f];
label.translatesAutoresizingMaskIntoConstraints = NO;
[_renameView addSubview:label];

约束:

constraints = [NSLayoutConstraint
               constraintsWithVisualFormat:@"H:|[_renameView]|"
               options:0
               metrics:nil
               views:views];

[self.view addConstraints:constraints];

constraints = [NSLayoutConstraint
               constraintsWithVisualFormat:@"H:|[separator]|"
               options:0
               metrics:nil
               views:views];

[_renameView addConstraints:constraints];

constraints = [NSLayoutConstraint
               constraintsWithVisualFormat:@"H:|-10-[label]-[_renameTextField]-10-|"
               options:NSLayoutFormatAlignAllCenterY
               metrics:nil
               views:views];

[_renameView addConstraints:constraints];

constraints = [NSLayoutConstraint
               constraintsWithVisualFormat:@"V:|-7-[_renameTextField(==36)]-7-[separator(==0.72)]|"
               options:0
               metrics:nil
               views:views];

[_renameView addConstraints:constraints];

更新

不明确布局的日志:

|   |   |   |   |   *<UIView:0x10c57d710>
|   |   |   |   |   |   *<UITextField:0x10c57d990> - AMBIGUOUS LAYOUT
|   |   |   |   |   |   |   <UIFieldEditor:0x10c60a150>
|   |   |   |   |   |   |   |   <_UIFieldEditorContentView:0x10c60a710>
|   |   |   |   |   |   |   |   |   <UITextSelectionView:0x10c038850>
|   |   |   |   |   |   |   |   |   |   <UIView:0x10c034730>
|   |   |   |   |   |   |   |   <UIImageView:0x10c60f790>
|   |   |   |   |   |   |   |   <UIImageView:0x10c60fad0>
|   |   |   |   |   |   |   <UIView:0x10c582620>
|   |   |   |   |   |   *<UIView:0x10c582700>
|   |   |   |   |   |   *<UILabel:0x10c5827e0> - AMBIGUOUS LAYOUT
|   |   |   |   |   *<_UILayoutGuide:0x10c582b50> - AMBIGUOUS LAYOUT

【问题讨论】:

【参考方案1】:

标签和文本字段之间水平轴上的空间分布不明确。尝试为标签设置内容拥抱优先级。我省略了垂直约束。

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[label]-[textField]-|"
                                                              options:0
                                                              metrics:nil
                                                                views:viewsDictionary]];

[label setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
[label setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];

【讨论】:

我已经更新了我的问题以显示报告的模棱两可 - 它是 UILabelUITextField。设置内容拥抱优先级实际上确实删除了模棱两可的报告 - 直到在文本字段中键入一个超长字符串,之后,如果我隐藏并重新显示它,模棱两可的布局就会返回。 你是对的,文本字段可以挤压标签,如果它的内容变长。我更新了我的答案以防止这种情况发生。【参考方案2】:

我已通过修复 UILabel 的宽度来消除不明确的布局。

constraints = [NSLayoutConstraint
               constraintsWithVisualFormat:@"H:|-10-[label(==50)]-[_renameTextField]-10-|"
               options:NSLayoutFormatAlignAllCenterY
               metrics:nil
               views:views];

[_renameView addConstraints:constraints];

无论内容有多长或多短,这在UITextField 中都有效。当然,我不得不硬编码标签的宽度,这是我试图避免的......

【讨论】:

查看@rshog 的回答。通过设置标签的内容拥抱优先级,它应该始终是正确的大小,即使文本发生变化。

以上是关于不明确的布局 - 我需要为两个并排视图添加哪些额外的约束?的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 使用自动布局

2 个按钮并排

使用自动布局和约束更改位置

当视图是多行时,约束布局如何摆脱 textview 上的额外空间

UIScrollview 底部的额外空白区域

无法在具有动态宽度的 Tablecell 中并排自动布局两个 UILabel