三个固定宽高的视图如何添加约束做到平分屏幕?

image

小引

前段时间面试,遇到这样一个布局问题。这个问题如果通过手写代码,或者StoryboardXIB加代码,都是很简单就可以实现的。但是,这个问题怎么会问的这么简单呢?前提是,不能写代码。

下面说说我想到的一些不需要写代码的布局方案,如果大家有更好的解决方案,欢迎评论讨论。


问题分析

三个等宽等高的View不管屏幕旋转,还是屏幕尺寸变化,这三个View都要做到平分屏幕。简单画个草图就可以得到以下信息:

  • 三个View两两间隙以及边缘View与屏幕边缘的间隙都是相同的;
  • 这三个View的中心点在屏幕的三等分点上。

有了这两个思路,问题就好解决了。


解决方案

方案一

通过添加辅助布局View来实现:通过添加四个辅助View(下图中灰色的View)来完成布局。

image
具体怎么实现,大家自行脑补吧。大致说下思路,四个辅助View等宽且宽度随屏幕宽度变化,另外三个View宽高固定,并添加好View之间的约束以及View与父视图间的约束即可。


方案二

此方案是针对于方案一的优化升级版:只需要添加两个辅助View即可实现需求。

image

思路:首先固定中间的View居中,然后添加的两个辅助View分别相对于中间居中的View和父视图添加约束,宽度伸缩,高度固定。这样,这两个辅助View的宽度在任何情况下都相等,然后在这两个辅助View里面分别添加上另外的View,这个View相对于辅助View居中即可。


方案三

此方法为进阶方案,当然你如果知道这个方法,也很简单。说它是进阶,是相对于前面两种方案来说的。因为,这种方案不需要添加辅助View

image

这个方法主要用到AutoLayout的一个API

1
2
3
4
5
6
7
+(instancetype)constraintWithItem:(id)view1
attribute:(NSLayoutAttribute)attr1
relatedBy:(NSLayoutRelation)relation
toItem:(id)view2
attribute:(NSLayoutAttribute)attr2
multiplier:(CGFloat)multiplier
constant:(CGFloat)c;

这个API的参数必须满足条件:view1.attr1 = view2.attr2 * multiplier + constant,这个条件中的multiplier是此方案的关键点。

通过上面的问题分析,我们可以设定三个view的中心点来达到效果。首先,设置中间的view居中。然后,设置左边view的中心点的x值为屏幕中心点x值的0.5倍,右边view的中心点的x值为屏幕中心点x值的1.5倍,这个倍数就是multiplier的值。

image

小结

以上就是三种简单的解决方案,如果你还有其他的解决方案,欢迎评论。


原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0