AutoLayout可保持视图大小成比例

Sim*_*ain 48 interface-builder ios autolayout ios6 nslayoutconstraint

我正在努力实现以下目标:

  • 我的xib中有2个视图需要保持20个像素的边缘(两侧和顶部)
  • 需要调整大小的2个视图的大小不同
  • 它们必须相隔20个像素
  • 它们的宽度需要相对于父视图的宽度保持不变

我阅读了一个关于这样做的教程并且它可以工作,但问题是它需要两个视图具有相同的宽度和引脚Widths equally,这是我不想要的.

这是我试过的:

  • 将前导空间约束添加到左视图为20像素
  • 将顶部空间约束添加到左视图为20像素
  • 将顶部空间约束添加到右视图为20像素
  • 将尾部空间约束添加到右视图为20像素
  • 将水平间距约束添加到两个视图为20像素

我遇到的问题是左视图没有调整大小,右视图填充空间以保持20像素的水平空间.

有没有办法让两个视图按比例调整它们应该填充的空间?

以下是我的布局和约束的屏幕截图:

xib布局约束定义

谢谢!

编辑

我尝试旋转设备时收到以下警告:

2012-10-11 08:59:00.435 AutolayoutTest[35672:c07] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want.
    Try this: (1) look at each constraint and try to figure out which you don't expect;
    (2) find the code that added the unwanted constraint or constraints and fix it. (Note:  
    If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x8a6b2b0 H:[UIView:0x8a6b1d0(170)]>",
    "<NSLayoutConstraint:0x8a68ad0 H:[UIView:0x8a69430(90)]>",
    "<NSLayoutConstraint:0x8a6ba40 H:[UIView:0x8a69430]-(20)-[UIView:0x8a6b1d0]>",
    "<NSLayoutConstraint:0x8a6ba00 H:[UIView:0x8a6b1d0]-(20)-|   (Names: '|':UIView:0x8a6b7e0 )>",
    "<NSLayoutConstraint:0x8a6b940 H:|-(20)-[UIView:0x8a69430]   (Names: '|':UIView:0x8a6b7e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x7199aa0 h=--& v=--& V:[UIView:0x8a6b7e0(568)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x8a6b2b0 H:[UIView:0x8a6b1d0(170)]>
Run Code Online (Sandbox Code Playgroud)

Ben*_*min 75

我可能迟迟没有提出解决方案,但这实际上可以在IB中轻松实现.

首先,将UIView添加到superview的所有四个边缘.

然后,添加您的第一子视图相应地,它的位置(IG:X = 0,Y = 0,身高=固定高度,宽度=你想相对于宽度的UIView,我们钉在所有四个边).

选择UIView第一个子视图并添加Equal Widths约束.当然,这将显示自动布局中的定位错误,但这没关系,因为这不是(还)你想要的.

现在就是诀窍:选择Equal Widths约束并将Multiplier编辑为您想要的比例(例如:如果您希望第一个子视图是UIView的1/4,则为1:4).重复第二个子视图和Tadaaaaaa的步骤!

在此输入图像描述

  • @Jessica:乘数属性是只读的.您必须删除旧的NSLayoutConstraint并将其替换为新的NSLayoutConstraint以进行修改.这可能看起来很麻烦,但它是Apple的设计.你别无选择.抱歉. (2认同)

Ian*_*n L 10

我是autolayout的新手,但遇到了你的问题并认为这将是一个很好的挑战.(这是我的警告,以防这不是理想的解决方案!)

您需要在代码中添加宽度约束.我通过首先在没有宽度约束的NIB中添加两个视图来实现这一点.这些是第一个(左)视图的约束:

在此输入图像描述

这些是我对第二个(右)视图的限制:

在此输入图像描述

这会在第二个视图中留下您不想要的额外约束 - 超视图和第二个视图之间的前导空间,如下所示:

在此输入图像描述

您无法在IB中删除该约束,因为它会留下不明确的布局(因为我们在子视图上没有宽度).但是,您可以在代码中删除它.首先,为它设置一个插座并在IB中连接它:

@property (nonatomic, strong) IBOutlet NSLayoutConstraint *view2superviewLeadingConstraint;
Run Code Online (Sandbox Code Playgroud)

然后,在视图控制器中viewDidLoad,您可以使用以下命令将其删除:

[self.view removeConstraint:self.view2superviewLeadingConstraint];
Run Code Online (Sandbox Code Playgroud)

最后,添加宽度约束.这里的关键是乘数参数,用于指定宽度基于超视图宽度的百分比.另请注意,您必须将常量参数设置为等于IB中设置的前导/尾随总数:

NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.3 constant:-20];
[self.view addConstraint:constraint1];

NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:self.view2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.7 constant:-40];
[self.view addConstraint:constraint2];
Run Code Online (Sandbox Code Playgroud)

  • 您不需要直接删除约束.在IB中,一次选择一个"占位符"约束(单击cog-down-arrow并选择"选择并编辑..."),然后选中"在构建时删除"框. (3认同)

Yat*_*B L 10

这可以通过添加一个虚拟视图(dummyView)来解决,其约束设置为固定宽度,高度并与Superview的centerX对齐.然后将左视图和右视图水平间距约束添加到dummyView.

在此输入图像描述 在此输入图像描述


Rém*_*rin 9

只需选择宽高比:

在此输入图像描述

  • 宽高比是什么?这是如何解决问题的? (5认同)

小智 6

正如其他人所提到的,关键是在"Pin Widths Equally"约束上设置一个乘数,以便视图宽度最终成为彼此的倍数.XCode 5.1应该添加在Interface Builder中设置它的能力,但除此之外,除了在代码中设置它之外,你还有另一种选择.如果创建"Pin Widths Equally"约束,则转到右侧Utilities面板中的Identity Inspector,然后查找"User Defined Runtime Attributes".使用键路径"multiplier"添加一个新属性,键入"number",并将值等于所需的比率.

乘数设置为运行时属性,如上所述.

这不会反映在Interface Builder中,但会在使用您的视图时应用.