iOS Autolayout中的约束
2015-04-02李岚李可嘉
李岚 李可嘉
摘 要:iOS中的Autolayout技术用于解决UI可视单元或元素的布局和排列问题并且能够可以完美的解决适配不同尺寸的屏幕以及解决横竖屏的问题,让编程不再枯燥无味,因此被越来越多的编程者所接受,Autolayout中的核心基础是约束,介绍了Autolayout中约束的研究意义,约束的类型和优先级,ContentSize约束,约束的装载方式和比较,最后对约束的使用提出了几点建议。
关键词:iOS;Autolayout;研究
1 Autolayout中约束的研究意义
Autolayout自动布局技术在iOS6就已经推出了,但是因为很多人一开始不习惯使用xib编程,而是坚持使用代码布局控件,所以Autolayout并没有普及的太快。但是现在随着越来越多的人开始使用xib,怎样适配横竖屏和不同尺寸的屏幕,成了亟待解决的问题,好在两年前就已经推出并且日臻完善的xib Autolayout技术可以完美的解决。对于Autolayout而言,最为核心的基础就是约束。
2 Autolayout中约束的类型
对于Autolayout而言,最为核心的基础就是约束,在iOS 中分别有以下几类约束:
NSLayoutConstraint,开放类。几乎是程序员最常用的约束。它用于设置view在view tree之间的关系,自身大小等。
NSContentSizeLayoutConstraint,私有类。用于衡量view内容和大小相关的约束。比如Hugging和Compression,控制view的内容显示。
NSAutoresizingMaskLayoutConstraint,私有類。由Autosizing mask转换到Autolayout系统中的约束表达。
_UILayoutSupportConstraint,私有类。布局支撑约束,它包括Top和Bottom的约束,用于控制view的显示边界,例如,它限制view的顶端显示不会和状态栏重合。
NSIBPrototypingLayoutConstraint,私有类。如果在Storyboard中添加了一个UI控件,且没有在Storyboard中添加任何约束,但是标注了要使用Autolayout,那么在实际的运行期,系统会默认为它添加NSIBPrototypingLayoutConstraint约束。
NSContentSizeLayoutConstraint最主要的作用是和intrinsic size一起工作,通常这个约束和Layout约束共同决定view的显示方式。
3 Autolayout中约束优先级
约束优先级通常是形容一个约束重要性的指标,两个约束如果共同决定一个显示属性的显示,当二者发生了抵触的时候,优先级表示其中一个约束,相比另外一个而言,更加重要。优先级就是浮点数,通常用其整数表达。
4 ContentSize约束
Autolayout系统有根据显示内容来自适应尺寸的能力。这个能力是由,Intrinsic Content Size内容大小、content hugging约束、content compression约束来共同决定。
Intrinsic Content Size保证了当view的内容变化后,自己适应内容的大小的描述。自定义View需要自己计算适合自己的intrinsic size。而imageview、label等含有内容控件(除了UITextView)都会自己计算“适合内容的Size”。
Content Hugging抗拉伸属性。它其实是一个约束,它使得它本身的大小更加贴合显示的内容。例如:如果一个UIView的内容显示需要200的宽度,那么如果UIView本身有宽度约束(此约束设置宽度为400),此时若抗拉伸属性的优先级比宽度约束要高,View本身的大小就不会变化,反之就会被拉伸。
Compression Resistance抗压缩属性。它的一切和抗拉伸相反。
Layout Constraints Layout约束是程序员必须熟悉的。一个线性公式就说明了它的意义:
view1.attr1=view2.attr2*multiplier + constant
这里=可以是>=,<=,<,>等。
剩余就是描述Layout Constraint的生成和装载方式:
生成方式比如:Layout Constraints的描述方式可以是原生NSLayoutConstraint来实现,也可以是VFL,也可以是自己封装的库。
5 Autolayout中约束的装载方式
(1)View形容它自己的约束(一元约束),添加到自己或者直系SuperView中。(2)View和View之间的约束,如果view之间是父子关系,添加到父亲上。如果view和view是兄弟关系,则添加到他们共同的父亲节点上。(3)View和View之间的约束,如果他们是两个不同的分支上的,则需要把约束添加到他们共同的祖先上面。
6 Autolayout中约束的比较
通常而言,比较对象,需要比较一个对象的所有成员变量。如果一一相等,则表明他们相等。但是,对于约束而言,这个比较方式比较例外:除了优先级以外的参数都要一致,才是一样的约束。也就是说优先级是不需要参与比较的。例如:
-(BOOL) isEqualToConstraint:(NSLayoutConstraint*) constraint
{
if (self.firstItem != constraint.firstItem) return NO;
if (self.secondItem != constraint.secondItem) return NO;
if (self.firstAttribute != constraint.firstAttribute) return NO;
if (self.secondAttribute != constraint.secondAttribute) return NO;
if (self.relation != constraint.relation) return NO;
if (self.multiplier != constraint.multiplier) return NO;
if (self.constant != constraint.constant) return NO;
return YES;
}
7 Autolayout中约束使用的几个建议
(1)充分利用约束的优先级。不要把所有约束的优先级都设置成Require。(2)约束没有顺序而言。优先级越高越会得到满足。(3)注意UpdateConstraint、Layoutsubview、DrawRect的顺序,在这个管线中的特定阶段做想自定义的事情。(4)注意约束描述的合理性,以避免自我矛盾的描述引起的Layout约束的冲突、歧义甚至崩溃。
参考文献
[1]Erica Sadun ,iOS Auto Layout Demystified,Second Edition[M].Addison-Wesley Educational Publishers Inc; 2nd Revised edition ,2013.
[2]关东升.iOS开发指南:从零基础到App Store上架(第2版)[M].人民邮电出版社,2014.