Autoresizing
autoresizing的核心思想:参照父容器来设置子控件的frame,不再写死frame,而是参照;
autoresizing只能设置当前控件与父控件之间的相对关系,当遇到需要设置兄弟控件之间的关系时,得使用autolayout;
autoresizing线的使用
外面4根线的作用:分别设置距离父容器的距离是否保持不变;
里面两根线的作用:表示子控件的宽和高是否随着父控件的宽高的变化而变化;
代码中使用autoresizing
view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleWidth;
// 顶部可拉伸(即底部与父控件的距离固定)|宽度可拉伸;
|符号赋值,枚举类型为二进制式值
0 0 00000000
2的0次方 1 00000001
2的1次方 2 00000010
2的2次方 4 00000100
Autolayout
通过设置某控件与任意其它控件之间的关系来决定如何显示该控件,不仅仅局限于父子控件;
两个核心概念
1.参照:通过参照其它控件或者父控件来设置当前控件的位置和大小;
2.约束:通过添加约束来限制控件的位置和大小;
注意:
<1>.通过margin设置topMargin时,需要根据具体需求选择margin的对象为statusBar或者其它;
<2>.同理,bottomMargin也要选择为控制器view或者tabBar;
<3>.并且需要取消选中Constrain to margins(6puls之后默认会添加左右16的距离,所以需要取消);
AutoLayout计算规则:
first item = (second item) * Multiplier + Constant
选中一个约束,通过属性面板查看属性
其中second item 可以选择约束view的Leading(left)或者Trailing(right)的值;
设置按钮左边居中:
first item = superview.center x
second item = targetview.Leading
autolayout和autoresizing是互斥的,同时只能使用其中之一。
无论是通过autoresizing还是autolayout,其实都是间接设置了控件的frame,所以一旦使用了autoresizing或者autolayout,就不要再设置控件的frame了;
size classes + Autolayout
通过autolayout设置的约束,约束一旦添加就会应用于各种屏幕(也就是说在不同屏幕下都使用相同的约束);而使用size classes + autolayout则可以为不同尺寸的屏幕设置不同的约束;
size classes技术主要解决的问题:为不同屏幕,通过auto layout设置不同的约束;
按钮,开关,文本框,标签,图片框等控件不需要设置宽高的约束也可以,因为这些控件的宽高都有默认值;
添加约束的规则
如果添加的约束和其它控件没有关系,则会添加到自己身上;
如果添加的约束是父子关系,设置子控件的约束,约束会添加到父控件上;
如果添加的约束两个控件是兄弟关系,则约束会添加到第一个共同的父控件上;
对于两个不同层级view之间的约束关系,则添加到他们最近的共同父view上;
通过代码实现Autolayout
1.利用NSLayoutConstraint类创建具体的约束对象;
2.添加约束对象到相应的view上;
-(void)addConstraint:(NSLayoutConstraint *);
-(void)addConstraint:(NSArray *);
代码实现Autolayout的注意点
1.要先禁止autoresizing功能,设置view的translatesAutoresizingMaskIntoConstraints属性为NO;
2.添加约束前,一定要保证相关的控件都已经在各自的父控件上;
3.不要再给view设置frame;
手动创建NSLayoutConstraint
+(id)constraintWithItem:(id)view1 // 要约束的控件
attribute:(NSLayoutAttribute)attr1 // 约束的类型(属性)
relatedBy:(NSLayoutRelation)relation // 与参照对象之间的关系
toItem:(id)view2 // 参照的控件
attribute:(NSLayoutAttribute)attr2 // 约束的类型(属性)
multiplier:(CGFloat)multiplier // 乘数(系数)
constant:(CGFloat)c; // 常量
obj1.property1 = (obj2.property2 * multiplier) + c;
常用约束类型
NSLayoutAttributeLeft ; // 左侧,右侧
NSLayoutAttributeTop: // 上方,下方
NSLayoutAttributeLeading; // 首部,尾部Trailing
NSLayoutAttributeWidth; // 宽度,高度
NSLayoutAttributeCenterX; // x轴中心,y轴
NSLayoutAttributeBaseline; // 文本底标线
NSLayoutAttributeNotAnAttribute; //没有属性
其中leading和left trailing和right正常情况下是等价的,通常都只用left和right;
参照关系
NSLayoutRelationEqual; // 相等
如果想参照statusBar,则toItem可以设置为self.topLayoutGuide(将toItem设置为控制器的topLayoutGuide属性),并设置参照的属性;
Autolayout动画
在修改了约束之后,只要执行一个UIView动画,则就能实现动画效果
viewTopConstraint.constant = 300;
[UIView animateWithDuration:1.0 animations:^{
[view layoutIfNeeded];
}];
注意
1.constant=300,只是修改了约束的值,并没有根据这个新的约束重新计算view的frame,如果没有调用view的layoutIfNeeded,系统将会在未来的生命周期中的某个时间自动重新计算view的frame;
2.在UIView动画中调用某个view的layoutIfNeeded方法,会先后更新这个view的约束,view的子控件的约束,view的父控件的约束;根据约束重新计算frame的值后再赋值;
3.修改约束的代码不需要放到动画中,原因是只有在layoutIfNeeded方法中才会修改frame,修改约束的代码只是改了约束,并没有及时更新frame;
size classes本质就是对所有的屏幕进行了分类,我们可以为不同类型的屏幕设置不同的约束;
仅仅是对屏幕进行了分类,真正摆放UI控件还是使用autolayout;
size classes中不再有横竖屏的概念,只有屏幕尺寸的概念;不再有具体尺寸的概念,只有抽象尺寸的概念;
把宽度和高度分为3种情况
1.compact (紧凑,小) 用 - 表示
2.regular (正常,大) 用 + 表示
3.any (任意,既可是compact,也可是regular) 用 * 表示;
通过这三种情况可以将屏幕分为9种类型;
exam1
设置Label的字体在竖屏下显示一种字体,在横屏下显示另外一种字体;
思路:
在wAny和hAny下添加一个Label;
查看Label字体属性旁边 + 号,再设置不同屏幕下显示不同的字体;
一般不要在wAny和hAny下设置约束,否则设置约束后,在其它尺寸的屏幕中再设置约束就会产生冲突,因为约束会被继承下来;
约束的继承关系
** 其它8种情况都会继承
*- 会被 - - \ + - 继承
+* 会被 + - \ - + 继承
快速设置约束
按住ctrl键拖线到另外一个控件上,然后设置约束。