我试图弄清楚如何使用自动布局(iOS6)和约束来做到这一点。
基本上,我的大视野在底部分为两个部分。在这些部分(当前为子视图)中,我具有图像视图和标签。我想用可变长的文本在两边居中。
我的头主要围绕自动布局,但是我不确定最好的方法。我倾向于认为在IB中是不可能的,但是在代码中。
继续尝试解决这个问题,但与此同时,这是我要创建的示例。
Answers:
这是你所追求的吗?
我通过viewCenteredInLeftSection
在您的视图中添加一个视图(名为)来完成此操作leftSection
,然后将时钟图像和标签添加为具有以下约束的子视图:
viewCenteredInLeftSection
的CenterX和CenterY等于其父视图(leftSection
)。clockImage
的顶部,底部和前缘等于其超级视图的(viewCenteredInLeftSection
)。label
的后沿等于其超级视图的(viewCenteredInLeftSection
)。clockImage
'的后沿到label
'的前沿相距标准距离。我无法在Interface Builder中调整iOS UIView的大小,因此我以OS X为例,而我完全可以在Interface Builder中做到这一点。如果您在Interface Builder中遇到上述约束时遇到麻烦,请告诉我,我将发布将创建它们的代码。
2014-08-26编辑
Luda,这是Xcode 5的Pin和Align菜单,也可以在Xcode的菜单栏中找到:
以下是我的示例在Interface Builder中的外观。蓝色视图是原始问题的“父视图”,即图像和标签应居中的给定视图。
我将绿色视图(我命名为viewCenteredInLeftSection
)添加为“父视图”的子视图。然后,我突出显示了它,并使用“容器中的水平中心”和“容器中的垂直中心”的对齐菜单来创建约束以定义其位置。
我将时钟图像添加为的子视图viewCenteredInLeftSection
,并定义了其宽度和高度。我突出显示了时钟图像和viewCenteredInLeftSection
,然后使用“对齐”>“前缘”,“对齐”>“上边缘”和“对齐”>“下边缘”应用了约束。
我将标签添加为的子视图viewCenteredInLeftSection
,并将其定位为距时钟图像的标准Aqua空间距离。我突出显示了标签和viewCenteredInLeftSection
,然后使用“对齐”>“后缘”应用了约束。
这是很多容易创建和Xcode 5的界面生成器与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]];
您还可以更改常量以在视图之间创建间隙。
-X
+X
我花了一些时间,但是我想出了一个非常可靠的解决方案。我想出了约翰·绍尔(John Sauer)提供的相同解决方案,但不想添加另一个视图来封装这些解决方案。
答案需要三个步骤。
1)包含其他两个子视图的子视图的宽度(我称之为leftInfoSection
)需要由其内容确定。这样一来,就无需对超级视图(或其他视图)具有左右约束来确定其宽度。这是很多东西的真正关键,就是让孩子们定义宽度。
2)我仍然必须在IB中有一个领先的约束才能使它具有有效的布局。(它需要知道leftInfoSection
水平放置的位置)。将一个约束连接到代码中,以便将其删除。除此之外,我还有一个垂直约束+ 3的约束GTE。
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]];
结果:
同样,IB可能会很烦恼它如何自动更新约束。当我尝试将子视图上的前导约束和尾随约束定义为0时,它将不断断开一个或另一个的连接,并对超级视图进行约束以定义宽度。诀窍是暂时将不需要的约束留在原处,但将其优先级降低到999。然后,我可以创建子视图约束来定义宽度。
斯坦福大学在ios 7上的演讲中考虑了一种解决方案,它的效果非常好。(这是sdfssfg ...东西是label1,而efsdfg ....东西是label2)
这工作得很好,但需要2个spacer 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]];
}
imageView
.lead = label
.trailing约束来使这项工作有效。可能我很胖。
有几种方法可以做到这一点。从根本上讲,这是如何将1..n个商品居中的方法,假设您所有商品的尺寸都受限制并且不会增长。
在物品的每一侧都放2个垫片。将垫片固定到父边缘。将您的第一个和最后一个项目锚定到锚点。最后,分配一个垫片,使其具有另一个垫片的宽度。您无需显式设置任何垫片大小,因为它将解决。
如果不是您想要的东西,而您和您的物品数量奇数,则将中间的物品居中放置在父物品的中心。另外,请确保第一项和最后一项没有锚定到父边。
如果不是您想要的东西,而您的物品数量是偶数,则将2个内部物品的边缘居中放置在父对象的中心。另外,请确保第一项和最后一项没有锚定到父边。
您还可以将一个不可见的占位符居中居中并固定在该占位符上,但是在约束时您仍然需要考虑奇数/偶数个项目,因此我不建议这种方法。