自动布局是一件很难掌握的事情。iOS9中StackViews和布局锚点的引入有些帮助,但理解如何创建特定布局仍然有些困难。在这篇文章中,我想关注一个经常发生的情况:你需要沿着一个轴放置一个固定比例的视图。它可能不是很明显,但可以通过乘法器中心对齐轻松满足这一要求,这种技术可以使用或不使用StackViews。问题想象一下,我们要构建这样一个布局,上面有两行imageview,它们是按照父view的宽高的一定比例来放置的。使用图像视图的原因是,如果不小心将它们拉伸或压缩,将会非常明显。布局保持相同的比例,因为视图适应不同的屏幕尺寸。这是横向模式下的相同视图:一旦您看到我们基于视图的中心对齐,您就会看到我们可以仅使用中心对齐约束来创建整个布局。对于每个imageView,我们需要一对约束来确定它在X轴和Y轴上的位置。一般的格式是这样的:imageView.CenterX=view.CenterX*modifierimageView.CenterY=view.CenterY*modifiermodifier参数将imageView放置在父v??iew大小的一定比例处,如下图:娱乐娱乐。创建这个布局有三种方法,第一种是使用IB,第二种是用代码添加约束,第三种是使用stackview。使用InterfaceBuilder创建约束对于每个图像视图,我们需要添加两个约束。使用文档大纲工具栏或按住Control键直接从图像视图拖动到视图画布中的父视图。每个添加一个“在容器中水平居中”和“在容器中垂直居中”约束。现在,编辑每个约束以设置我们需要的百分比。以下是左上角心脏图像视图的水平和垂直约束设置:请注意,这也是向我们的约束添加标识符的好时机。当你完成后,你应该已经添加了10个约束,就像这样:在代码中创建约束在查看添加约束的代码之前,我想提一个常见的错误,当使用代码添加视图时,你需要关闭自动调整大小视图的从掩码到约束的过渡。如果不这样做,系统会自动创建约束条件,会和我们创建的约束条件发生冲突。//...codetocreateimageview...imageView.translatesAutoresizingMaskIntoConstraints=falseview.addSubview(imageView)有几种方法可以创建这些约束,我将在视图控制器的viewDidLoad方法中创建这些约束。一个简单的辅助函数会创建每个NSLayoutConstraint的过程就没有那么麻烦了:attribute,relatedBy:.Equal,toItem:view,attribute:attribute,multiplier:multiplier,constant:0)constraint.identifier=identifierview.addConstraint(constraint)}}这创建并添加了一个相对于父视图的约束(使用视图控制器的视图属性)。NSLayoutAttribute参数是水平约束的.CenterX和垂直约束的.CenterY。例如,这是上面一行中心脏图像视图的约束://verticalconstraintaddConstraintFromView(heartTop,attribute:.CenterY,multiplier:0.667,identifier:"heartTopcenterY")//horizo??ntalconstraintaddConstraintFromView(heartTop,attribute:.CenterX),multiplier:0.5,identifier:"heartTopcenterX")其他类似,所有设置见示例代码。使用堆栈视图怎么样?每当你遇到水平或垂直布局的问题时,你应该想到堆栈视图。将图像视图添加到堆栈视图非常简单,但是如何配置呢?我们不希望stackview布满视图,所以Axis选择水平轴,使用“EqualSpacing”分布方式:现在我们需要约束stackview的大小和位置:设置每个的垂直位置堆栈视图的方式与设置图像视图的垂直位置相同。使用修饰符中心约束(例如,带有stackView.centerY=0.667*superview.centerY约束的顶部堆栈视图)。向每个堆栈视图添加水平居中约束。***的约束需要一点技巧,我们需要确定stackview的宽度,使用stackview的前缘和后缘是最简单的方法:左上角的imageview的中心应该是0.5乘以父视图的中心。然后我们需要将堆栈视图的左侧向左移动图像视图宽度的一半。imageview的尺寸是100x100,所以我们需要在constraint中减去50:注意在IB中添加这个constraint的时候,需要把第二项改成superviewcenter,equalspacingdistribution会帮我们修正trailingposition.以类似的方式处理下面的堆栈视图,所以我们最终的结果如下:这是我发现在代码中添加约束比在IB情况下编辑要容易得多的一种方式,尤其是当我们可以计算图像视图的大小时运行。2016-01-31更新:有一个更简单的方法,在最左边的图像的中心添加一个约束,堆栈视图将调整大小以适合,而不需要计算图像的大小。有关详细信息,请参阅代码。补充阅读你可以在GitHubCodeExamples上找到这篇文章的代码,它包含三个版本的IB,代码和堆栈视图,你可以比较这些方法。
