使用Auto Layout处理比例间距问题
使用Auto Layout处理比例间距问题
Auto Layout 是一个掌握起来很具有挑战性的东西。iOS 9引入的 Stack Views和 layout 锚点有一些帮助,但是明白如何创建特定的 layout仍有一定难度。
在这篇文章中我想着眼于一个经常出现的情形: 你需要沿一个轴向按固定比例放置视图。可能并不是十分明显, 但是这个需求可以通过 一个multiplier中心对齐来轻松实现,它是一种在有无Stack Views情况下都可以使用的技术。
问题
设想我们要构建这样一个布局,上面有两排图片视图,都是基于父视图宽度和高度的某一百分比放置。之所以使用图片视图, 是因为如果意外地把它们拉伸或压缩了, 可以十分明显得看出来。
当视图适应不同的屏幕大小时, layout 会保持相同的比例。下面是同一个视图在横屏模式下的情形:
一旦你看出来我们是基于视图中心进行对齐的,你就会发现我们可以只使用中心对齐约束来创建整个布局。对每个imageView,我们需要一对约束来确定其在X轴和Y轴的位置,一般的格式是这样的:
imageView.CenterX = view.CenterX * modifier
imageView.CenterY = view.CenterY * modifier
modifier参数将imageView放置在父视图尺寸的某个百分比的位置上,如下所示:
寓教于乐。这里有三种方式来创建该布局,第一是使用 IB, 第二是用代码添加约束,第三是使用 stack view.
使用Interface Builder创建约束
对每个 image view 我们需要添加两个约束。使用文档大纲工具栏或者直接在视图画布中按住 control 键从 image view 中拖拽到父视图上。每一个都添加一个“Center Horizontally in Container”和“Certer Vertically in Container”约束。
现在, 编辑每个约束来设置我们需要的百分比例。下面是左上角的红心图片视图的水平和垂直约束设置:
注意这也是给我们的约束添加identifiers 的好时机。完成后,你应该添加了10个约束,如下所示:
以代码形式创建约束
在看添加约束的代码之前,我要提下一个常见的错误,当使用代码添加视图时, 你需要关闭视图的 autoresizing mask 向 constraints 的转变。如果不这样做,系统会自动创建约束,这会和我们创建的约束发生冲突。
//...code to create image view...
imageView.translatesAutoresizingMaskIntoConstraints =
false
view.addSubview(imageView)
有几种创建这些约束的方法,我将会在视图控制器的 viewDidLoad 方法中创建. 一个简单的辅助函数会使创建每个 NSLayoutConstraint 的过程不那么麻烦:
func addConstraintFromView(subview: UIView?,
attribute: NSLayoutAttribute,
multiplier: CGFloat,
identifier: String) {
if
let subview = subview {
let constraint = NSLayoutConstraint(item: subview,
attribute: attribute,
relatedBy: .Equal,
toItem: view,
attribute: attribute,
multiplier: multiplier,
constant: 0)
constraint.identifier = identifier
view.addConstraint(constraint)
}
}
这样就可以创建并添加一个相对于父视图的约束 (使用视图控制器的 view 属性)。NSLayoutAttribute 参数在水平约束中为 .CenterX,在竖直约束中为 .CenterY。例如,下面是上面一行的红心图片视图的约束:
// vertical constraint
addConstraintFromView(heartTop,
attribute: .CenterY,
multiplier: 0.667,
identifier:
"heartTop center Y"
)
// horizontal constraint
addConstraintFromView(heartTop,
attribute: .CenterX,
multiplier: 0.5,
identifier:
"heartTop center X"
)
剩下的和这个类似,全部设置见示例代码。
使用Stack View呢?
无论何时只要你遇到水平或垂直布局的问题,你就要想到 stack view。向 stack view 中添加 image views 是很简单的,但是如何配置呢? 我们不想让stack view中堆满views, 所以 Axis 选择水平轴向, 使用“Equal Spacing”分布方式:
现在我们需要约束 stack view 的大小和位置:
使用和设置图片视图竖直位置相同的方式设置每个 stack view 的竖直位置。使用modifier中心约束 (例如顶部 stack view 使用 stackView.centerY = 0.667 * superview.centerY 约束)。
向每个 stack view 添加一个水平居中的约束。
最后的约束需要一点小小的技巧,我们需要确定 stack view 的宽度,使用 stack view 的 leading 和 trailing 边缘是最简单的方式:
左上的 image view 的中心应该是父视图中心的 0.5 倍. 那么我们需要 stack view 的左边向左移动image view 宽度的一半. image view 大小时 100x100, 所以我们需要在约束中减去 50:
注意在 IB 中添加这个约束时你需要改变第二项为 superview center,equal spacing 分布方式将会为我们修正 trailing 位置. 用类似的方法处理下方的 stack view,于是我们最终结果如下:
这是我发现的一种用代码添加约束要比在IB中编辑简单得多的一种情形,尤其是当我们可以在运行时计算 image view 的大小时。
2016-01-31 更新: 还有一个更简单的方法,为最左边图片的中心添加一个约束,stack view 会改变大小来适应,而不需要计算图片的大小。详见代码。
补充阅读
你可以在 GitHub CodeExamples( https://github.com/kharrison/CodeExamples/tree/master/AutoLayout )上找到这篇帖子的代码,它包含IB、代码和 stack view 三个版本,你可以比较下这几个方法。
使用Auto Layout处理比例间距问题的更多相关文章
- WWDC2016 Session笔记 - Xcode 8 Auto Layout新特性
目录 1.Incrementally Adopting Auto Layout 2.Design and Runtime Constraints 3.NSGridView 4.Layout Feedb ...
- 【转】使用 Auto Layout 的典型痛点和技巧
layoutIfNeeded()强制立刻更新布局 原文网址:http://www.jianshu.com/p/0f031606e5f2 官方文档:Auto Layout Guide 加上去年WWDC上 ...
- iOS之Xcode8 Auto Layout新特性
目录 1.Incrementally Adopting Auto Layout 2.Design and Runtime Constraints 3.NSGridView 4.Layout Feedb ...
- WWDC2016 Session笔记 – Xcode 8 Auto Layout新特性
目录 1.Incrementally Adopting Auto Layout 2.Design and Runtime Constraints 3.NSGridView 4.Layout Feedb ...
- Swift语言Auto Layout入门教程:上篇
原文:Beginning Auto Layout Tutorial in Swift: Part 1/2,译者:@TurtleFromMars 开始用自动布局约束的方式思考吧! 更新记录:该教程由Br ...
- iOS发展 ---- 至iPhone 6自适应布局设计 Auto Layout
Apple从iOS 6增加了Auto Layout后開始就比較委婉的開始鼓舞.建议开发人员使用自适应布局,可是到眼下为止,我感觉大多数开发人员一直在回避这个问题,无论是不是因为历史原因造成的,至少他们 ...
- (七)unity4.6Ugui中国教程文档-------摘要-UGUI Auto Layout
大家好,我是太阳广东. 转载请注明出处:http://write.blog.csdn.net/postedit/38922399 更全的内容请看我的游戏蛮牛地址:http://www.unityman ...
- 【转】(七)unity4.6Ugui中文教程文档-------概要-UGUI Auto Layout
原创至上,移步请戳:(七)unity4.6Ugui中文教程文档-------概要-UGUI Auto Layout 6. Auto Layout Rect Transform布局系统是足够灵活,可以处 ...
- iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束
http://blog.csdn.net/pucker/article/details/41843511 上一篇文章<iOS 8界面自动布局系列-1>简要介绍了iOS界面布局方式的前世今生 ...
随机推荐
- CSS编码规范(转)
1 前言 CSS作为网页样式的描述语言,在百度一直有着广泛的应用.本文档的目标是使CSS代码风格保持一致,容易被理解和被维护. 虽然本文档是针对CSS设计的,但是在使用各种CSS的预编译器(如less ...
- HDU——1233还是畅通工程(克鲁斯卡尔+优先队列)
还是畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- [luoguP3231] [HNOI2013]消毒(最小点覆盖 + 状压)
传送门 考虑贪心,控制某一维为1,另两位最大是最优的,也就是一次选一个厚度为1的面 那么对于每个点,可以有3种面是可以选到它的 然后gg 考虑二维的状态,一个平面,有些点,一次选一行或一列最优 那么每 ...
- 从实际案例聊聊Java应用的GC优化
转自美团点评技术博客:https://tech.meituan.com/jvm_optimize.html 当Java程序性能达不到既定目标,且其他优化手段都已经穷尽时,通常需要调整垃圾回收器来进一步 ...
- bzoj 2437[Noi2011]兔兔与蛋蛋 黑白染色二分图+博弈+匈牙利新姿势
noi2011 兔兔与蛋蛋 题目大意 直接看原题吧 就是\(n*m\)的格子上有一些白棋和一些黑棋和唯一一个空格 兔兔先手,蛋蛋后手 兔兔要把与空格相邻的其中一个白棋移到空格里 蛋蛋要把与空格相邻的其 ...
- hdu 4870 rating(高斯消元求期望)
Rating Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- 定位 UNIX 上常见问题的经验总结
本文主要对 UNIX 平台常见的问题进行了分类,介绍一些常见问题分析时使用的方法和命令,对以下三种常见问题的分析方法做了简单介绍:UNIX 下 Crash 问题的分析方法.UNIX 下内存泄露问题的分 ...
- PHP使用JpGraph绘制折线图
PHP使用JpGraph绘制折线图 下载jpgraph类库,使用的是src目录下的类文件. require_once './src/jpgraph.php'; require_once './src/ ...
- Tomcat是怎么工作的(2) -- 动手实现山寨版的简单Web Server
本文先讲解一下Java web server都是怎么工作的.web server也叫HTTP server——顾名思义它是用HTTP协议和客户端交互的.客户端一般就是各种各样的浏览器了.相信所有朋友都 ...
- LeetCode OJ-- Spiral Matrix II
https://oj.leetcode.com/problems/spiral-matrix-ii/ 螺旋矩阵,和题目一一样的思路,这个是产生n*n 矩阵. #include <iostream ...