想象一下这个场景。你有一个UIImageView和一个UIButton。第一个是300x360,第二个是210x70。 imageview
包含目录图像,button
表示“打开目录”。
我想根据这些要求在主视图中定位元素:
两个元素应该水平居中,即center.x坐标应该全部相等(视图,图像和按钮);
这两个元素应按以下方式垂直居中:分隔符(灵活) - imageview - 分隔符(固定,假设30分) - 按钮 - 分隔符(灵活)。最上面和最下面的分隔符应该具有相同的大小(这是居中的含义)。
我无法使用NSLayoutConstraint使其工作。
到目前为止,我所做的一直是使用NSLayoutAttributeCenterX
和NSLayoutRelationEqual
将两个元素的X坐标居中到相同的view
属性。
根据我的想法,最后一部分是修复它们的垂直对齐。
我尝试使用@"V:|-[imageview(360)]-[button(70)]-|"
,但无效(Unable to simultaneously satisfy constraints.
)。
如果我使用@"V:|-[imageview(360)]-[button]-|"
,我会把一切都搞定。也就是说,顶部是完美的,但按钮是拉伸的,以填补内部分隔符和视图底部之间的空隙。
如何让这些元素固定大小,让自动布局只是弄清楚如何将它们放在视图中?
答案 0 :(得分:10)
我能够通过做这样的事情来做到这一点:
NSNumber *sepHeight = @60.0F;
// Center the two views horizontally
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
// Position the two views one below the other, using the separator height defined above
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[imageview]-sepHeight-[button]"
options:0
metrics:NSDictionaryOfVariableBindings(sepHeight)
views:views]];
// Force the button distance from the bottom to be the half of the size of the content
CGFloat constant = (imageview.frame.size.height + button.frame.size.height + [sepHeight floatValue]) / 2.0;
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:constant]];
棘手的部分是常数值。该值是所有视图高度的一半,包括它们的分隔符。这意味着,如果imageview的高度为360,按钮的高度为70,分隔符为60,则该常量将为(360 + 70 + 60)/ 2 = 245。
确实应该有一种更聪明的方式,但是现在我认为这没问题。
答案 1 :(得分:5)
有两种方法可以解决这个问题。
正如@uchuugaka建议的那样,将您的imageview和按钮放在容器视图中。如果将子视图固定到容器的边缘(您将相应地调整大小 - 高度为360 + 30 + 70 == 460),则不会出现相同的居中问题。然后,您可以将此容器置于视图的中心位置简单的align-center-Y约束。
您可以使用间隔视图。通过添加两个隐藏视图,您可以指定约束以将它们定位在图像视图和按钮的上方/下方,具有相同的高度,例如它们充当弹簧。以下是使用您的维度执行此操作的代码:
- (void) viewDidLoad
{
[super viewDidLoad];
UIView* imageview = [UIView new];
imageview.backgroundColor = [UIColor blueColor];
imageview.translatesAutoresizingMaskIntoConstraints = NO;
UIView* button = [UIView new];
button.backgroundColor = [UIColor greenColor];
button.translatesAutoresizingMaskIntoConstraints = NO;
UIView* spacer1 = [UIView new];
spacer1.backgroundColor = [[UIColor redColor] colorWithAlphaComponent: 0.5];
spacer1.translatesAutoresizingMaskIntoConstraints = NO;
spacer1.hidden = YES; // comment out to show spacer!
UIView* spacer2 = [UIView new];
spacer2.backgroundColor = [[UIColor redColor] colorWithAlphaComponent: 0.5];
spacer2.translatesAutoresizingMaskIntoConstraints = NO;
spacer2.hidden = YES; // comment out to show spacer!
[self.view addSubview: imageview];
[self.view addSubview: button];
[self.view addSubview: spacer1];
[self.view addSubview: spacer2];
NSDictionary* views = NSDictionaryOfVariableBindings( imageview, button, spacer1, spacer2 );
NSArray* constraints;
constraints = [NSLayoutConstraint constraintsWithVisualFormat: @"V:|[spacer1(==spacer2)][imageview(360)]-30-[button(70)][spacer2(==spacer1)]|"
options: 0
metrics: nil
views: views];
[self.view addConstraints: constraints];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageview
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:300]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:210]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:imageview
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:button
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
}
答案 2 :(得分:0)
您需要使垂直空间等于或大于图像视图顶部和按钮底部。 但是,这听起来似乎更容易在包含图像和按钮的其他视图上。然后在超视图中将视图V和H居中。
自动布局有时仍表示容器视图。