自动布局(约束)中心2在父视图中并排显示

Bob*_*ryn 69 iphone constraints ios autolayout

我试图弄清楚如何使用自动布局(iOS6)和约束来做到这一点.

基本上我将我的大视图分为底部的两个部分.在这些部分(目前是子视图)内部,我有一个图像视图和一个标签.我希望以两边为中心,使用可变长度的文本.

我的头脑主要是围绕汽车布局,但我不确定最好的方法.我倾向于认为这在IB中是不可能的,但是在代码中.

继续尝试解决这个问题,但与此同时,我正在努力创建这个例子.

在此输入图像描述

Joh*_*uer 65

这就是你要追求的吗?

短标签 长标签

我通过viewCenteredInLeftSection在您的视图中添加一个视图(命名)leftSection,然后将时钟图像和标签添加为具有这些约束的子视图来完成:

  • 使得viewCenteredInLeftSectionCenterX和CenterY等于其superview的(leftSection).
  • 使得clockImageTop,Bottom和Leading的边缘等于其superview的(viewCenteredInLeftSection).
  • 使得后label缘等于其超级视图(viewCenteredInLeftSection).
  • 使后clockImage缘距离前缘的标准距离label.

viewCenteredInLeftSection

我无法在Interface Builder中调整iOS UIViews的大小,所以我为OS X制作了我的示例,我完全可以在Interface Builder中完成.如果您在Interface Builder中遇到上述限制时遇到问题,请告诉我,我将发布将创建它们的代码.

2014-08-26编辑

Luda,这里是Xcode 5的Pin和Align菜单,也可以在Xcode的菜单栏中找到:

对齐菜单 Pin菜单

下面是我的示例在Interface Builder中的样子.蓝色视图是原始问题的"父视图",即给定视图,图像和标签应居中.

我添加了绿色视图(我命名viewCenteredInLeftSection)作为"父视图"的子视图.然后我突出显示它并使用"对齐"菜单"容器中的水平中心"和"容器中的垂直中心"来创建约束以定义其位置.

我添加了时钟图像作为子视图viewCenteredInLeftSection,其中约束定义了它的宽度和高度.我突出显示时钟图像viewCenteredInLeftSection,然后使用"对齐">"前沿","对齐">"顶边"和"对齐">"底边"应用约束.

我将标签添加为子视图viewCenteredInLeftSection,将其定位为与时钟图像的标准Aqua空间距离.我突出显示了标签viewCenteredInLeftSection,然后使用"对齐">"尾随边缘"应用了约束.

使用Xcode 5的Interface Builder与Xcode 4相比,这容易创建.

Interface Builder

  • “使clockImage的顶部,底部和前沿等于其超级视图的”是什么意思?可以在Interface Builder中完成吗? (2认同)

Luc*_*ien 29

我想出了一种不添加其他视图的方法:

 [aView addConstraint:[NSLayoutConstraint constraintWithItem:viewOnLeft attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationLessThanOrEqual toItem:aView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
 [aView addConstraint:[NSLayoutConstraint constraintWithItem:viewOnRight attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationLessThanOrEqual toItem:aView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
Run Code Online (Sandbox Code Playgroud)

您还可以更改常量以在视图之间创建间隙.

  • 左视图约束常量: -X
  • 右视图约束常数: +X

居中子视图

  • 这似乎将左视图的右侧和右视图的左侧与其容器的中心对齐.如果左侧视图和右侧视图具有大致相同的宽度,则这看起来很好.但是,如果一方比另一方明显更宽,那肯定会看起来不平衡. (16认同)

Bob*_*ryn 16

我花了一点时间,但我找到了一个非常可靠的解决方案.我想出了John Sauer提供的相同解决方案,但不想添加另一个视图来包装这些.

答案需要三个步骤.

1)我的子视图的宽度包含其他两个,我将调用它leftInfoSection,需要由它的内容决定.这使得它不需要对超视图(或其他视图)具有左右约束来确定它的宽度.这是一个真正的关键,很多东西都是让孩子们定义宽度.

在此输入图像描述

2)我仍然必须在IB中有一个主要约束,因为它有一个有效的布局.(它需要知道leftInfoSection水平放置的位置).将一个约束连接到您的代码中,以便您可以删除它.除此之外,我有一个尾随约束GTE垂直分频器+3.

3)最后的关键是考虑你必须使用哪些信息(在代码中,因为IB是有限的).我意识到我知道我的部分上方的水平分隔线的中心,并且我leftInfoSection的中心将是该水平条的中心减去水平条宽度的1/4.这是左侧和右侧的最终代码:

// remove the unwanted constraint to the right side of the thumbnail
[self.questionBox removeConstraint:self.leftInfoViewLeadingConstraint];
// calculate the center of the leftInfoView
CGFloat left = self.horizontalDividerImageView.frame.size.width/4 * -1;
// constrain the center of the leftInfoView to the horizontal bar center minus a quarter of it to center things
[self.questionBox addConstraint:[NSLayoutConstraint constraintWithItem:self.leftInfoView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.horizontalDividerImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:left]];

// remove the unwanted constraint to the right side of the questionBox
[self.questionBox removeConstraint:self.rightInfoViewTrailingConstraint];
// calculate the center of the rightInfoView
CGFloat right = left * -1;
// constrain the center of the rightInfoView to the horizontal bar center plus a quarter of it to center things
[self.questionBox addConstraint:[NSLayoutConstraint constraintWithItem:self.rightInfoView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.horizontalDividerImageView attribute:NSLayoutAttributeCenterX multiplier:1 constant:right]];
Run Code Online (Sandbox Code Playgroud)

结果: 最后结果

此外,IB可能会非常讨厌它如何自动更新约束.当我试图将子视图上的前导和尾随约束定义为0时,它将保持断开一个或另一个并对超视图进行约束以定义宽度.诀窍是暂时保留不需要的约束,但将其优先级降低到999.然后我能够创建但子视图约束来定义宽度.


Vin*_*mar 15

在斯坦福大学的ios 7讲座中考虑了这方面的解决方案.它工作得很漂亮.这里有解决方案.(这里sdfssfg ......东西是label1和efsdfg ....东西是label2)

在此输入图像描述

  • 观看此视频https://www.youtube.com/watch?v=pv1EHGEf884(48分钟后他将解释上述问题) (6认同)
  • 基本上用两个透明的uiviews(比如V1和V2)附加那些所需的两个标签(比如L1和L2).V1和V2应该具有相同的宽度,并且所有四个视图应该被分配为:-V1-L1-L2-V2- .这里的连字符是它们之间的水平距离(约束)可以是任何值.保持零我会建议. (2认同)

小智 11

这很好用,但需要2个间隔UIView:

UIView *spacer1 = [[UIView alloc] init];
spacer1.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:spacer1];

UIView *spacer2 = [[UIView alloc] init];
spacer2.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:spacer2];

NSDictionary *views = NSDictionaryOfVariableBindings(spacer1, spacer2, imageView, label);

[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[spacer1(>=0)][imageView]-4-[label][spacer2(==spacer1)]|" options:0 metrics:nil views:views];

for (int i = 0; i < constraintsArray.count; i++) {

    [self.view addConstraint:constraintsArray[i]];
}
Run Code Online (Sandbox Code Playgroud)


alc*_*mla 5

在iOS 9之后,实现此目的的另一个选择是使用堆栈视图

  • 一个例子就是一个更好的答案. (4认同)
  • 适用于iOS 9.0及更高版本 (3认同)