自动布局(约束)在父视图中居中显示2个视图
我想弄清楚如何做到这一点与自动布局(iOS6)和约束。
基本上我把我的大视野分为两部分。 里面的部分(目前子视图)我有一个图像视图和标签。 我想以两边为中心,用可变长度的文本。
我的头大部分是围绕自动布局,但我不确定最好的办法。 我倾向于认为这是不可能在IB,但在代码。
继续尝试弄清楚这一点,但在此期间,我正在试图创build这个例子。
这是你在追求什么?
我在viewCenteredInLeftSection
的部分添加了一个视图(命名为viewCenteredInLeftSection
),然后添加时钟图像和标签作为子视图,这些约束是:
- 使
viewCenteredInLeftSection
的CenterX和CenterY等于它的leftSection
视图(leftSection
)。 - 使
clockImage
的Top,Bottom和LeadingviewCenteredInLeftSection
等于它的viewCenteredInLeftSection
视图(viewCenteredInLeftSection
)。 - 使
label
的后沿等于其viewCenteredInLeftSection
视图(viewCenteredInLeftSection
)。 - 使
clockImage
的后缘与label
的前缘保持标准距离。
我无法在界面生成器中调整iOS UIView的大小,所以我做了OS X的示例,而且我完全可以在界面生成器中完成。 如果在Interface Builder中遇到上述限制时遇到困难,请告诉我,我将发布将会创build它们的代码。
2014-08-26编辑
路达 ,这里是Xcode 5的Pin和Align菜单,也可以在Xcode的菜单栏中find:
下面是我的例子在Interface Builder中的样子。 蓝色视图是原始问题的“父视图”,图像和标签应该以给定视图为中心。
我添加了绿色视图(我命名viewCenteredInLeftSection
)作为“父视图”的子视图。 然后我突出显示它,并使用alignment菜单“容器中的水平中心”和“容器中的垂直中心”创build约束来定义其位置。
我添加了时钟图像作为viewCenteredInLeftSection
子视图,约束定义其宽度和高度。 我突出显示了时钟图像和viewCenteredInLeftSection
,然后使用“alignment”>“ viewCenteredInLeftSection
边”,“alignment”>“ viewCenteredInLeftSection
”和“alignment”>“ viewCenteredInLeftSection
应用约束。
我将标签添加为viewCenteredInLeftSection
的子视图,将其定位为与时钟图像的标准Aqua空间距离 。 我突出标签和viewCenteredInLeftSection
,然后应用约束使用Align> Trailing Edges。
使用Xcode 5的Interface Builder与Xcode 4相比,这样做更容易。
我想出了一个方法,而不添加另一个视图:
[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]];
您还可以更改常量以在视图之间创build间隙。
- 左视图约束常量:
-X
- 右视图约束常量:
+X
我花了一段时间,但我find了一个非常稳固的解决scheme。 我想出了约翰·绍尔提供的同样的解决scheme,但不想增加另一种观点来包装这些解决scheme。
答案需要三步。
1)包含其他两个我调用leftInfoSection
子视图的宽度需要由其内容决定。 这消除了它需要对超视图(或其他视图)的左右约束来确定它的宽度。 这是一个真正的关键,有很多这个东西是让宽度由儿童定义。
2)我仍然必须在IB有主要的约束,因为它有一个有效的布局。 (它需要知道在哪里放置leftInfoSection
水平)。 把那个约束连接到你的代码中,这样你就可以删除它。 除此之外,我有一个尾随约束GTE的垂直分频器+3。
3)最后的关键是考虑你需要处理的信息(在代码中,因为IB是有限的)。 我意识到,我知道我的部分上方的水平分隔线的中心,并且我的leftInfoSection
部分的中心将是该水平条的中心减去水平条宽度的四分之一。 以下是左侧和右侧的最终代码:
// 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]];
结果:
另外,IB可能会非常恼火地自动更新约束条件。 当我试图定义子视图的前导和尾随约束为0时,它将保持断开其中一个或另一个,并对superview进行约束以定义宽度。 诀窍是暂时将不需要的约束留在原地,但将其优先级降低到999.然后,我可以创build子视图约束来定义宽度。
在斯坦福大学的ios 7讲座中考虑了这个问题的解决scheme。它的工作非常漂亮。在这里附上了解决scheme。 (这里sdfssfg …东西是label1和efsdfg ….东西是label2)
这工作相当好,但需要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]]; }
在iOS 9之后,另一个select是使用Stack Views
你可能想引用这个
基于百分比的标记
基本上,它说,首先与一些不正确的边际,然后纠正与父母的看法。
与我的情况一起工作。