1. 屏幕适配的发展历史
- iPhone3GS/iPhone4
- 没有屏幕适配可言
- 全部用frame,bounds,center进行布局
- 很多这样的现象:坐标值,宽度高度值全部写死
UIButton *btn = [[UIButton alloc]init];
btn.frame = CGRectMake(0,0,320 - 20,480 - 30);
iPad出现,iPhone横屏
- 出现Autoresizing技术
- 让子控件可以跟随父控件的行为自动发生相应的变化
前提是:关闭Autolayout功能
局限性
- 只能解决子控件跟父控件的相对关系问题
- 不能解决兄弟控件的相对关系问题
iOS 6.0(Xcode4)开始
- 出现Autolayout技术
- 从Xcode5.0(iOS 7.0)开始,开始流行Autolayout
2.使用Autoresizing适配
方法一:通过storyboard或xib中设置
方法二:通过代码适配
/**
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0, 距离父控件左边的间距是伸缩的(不固定的)
UIViewAutoresizingFlexibleRightMargin = 1 << 2, 距离父控件右边的间距是伸缩的(不固定的)
UIViewAutoresizingFlexibleTopMargin = 1 << 3, 距离父控件顶部的间距是伸缩的(不固定的)
UIViewAutoresizingFlexibleBottomMargin = 1 << 5, 距离父控件底部的间距是伸缩的(不固定的)
UIViewAutoresizingFlexibleWidth = 1 << 1, 宽度跟随父控件的宽度进行自动伸缩
UIViewAutoresizingFlexibleHeight = 1 << 4, 高度跟随父控件的高度进行自动伸缩
*/
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
blueView.frame = CGRectMake(0, 0, 250, 250);
[self.view addSubview:blueView];
self.blueView = blueView;
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
redView.frame = CGRectMake(0, 150, 250, 100);
/**使redView位于屏幕右下角*/
redView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
[blueView addSubview:redView];
/**arc4random_uniform(100) 产生1~100之间的随机数*/
CGFloat w = 200 + arc4random_uniform(100);
CGFloat h = 200 + arc4random_uniform(100);
self.blueView.frame = CGRectMake(0, 0, w, h);
3.使用Autolayout适配
- 方法一:storyboard中添加约束
- Autolayout的2个核心概念:参照,约束
- 方法二:代码实现Autolayout
- 步骤
- 利用NSLayoutConstraint类创建具体的约束对象
- 添加约束对象到相应的view上
创建约束对象的常用方法
+(id)constraintWithItem:(id)view1 attribute: (NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
view1 :要约束的控件
attr1 :约束的类型(做怎样的约束)
relation :与参照控件之间的关系
view2 :参照的控件
attr2 :约束的类型(做怎样的约束)
multiplier :乘数
c :常量
- 代码实现Autolayout的注意点
- 要先禁止autoresizing功能,设置view的下面属性为NO(不要将AutoresizingMask转为Autolayout的约束)
view.translatesAutoresizingMaskIntoConstraints = NO; - 添加约束之前,一定要保证相关控件都已经在各自的父控件上
- 不用再给view设置frame
- 自动布局的核心计算公式
obj1.property1 =(obj2.property2 * multiplier)+ constant value
- 要先禁止autoresizing功能,设置view的下面属性为NO(不要将AutoresizingMask转为Autolayout的约束)
- 步骤
- 添加约束的规则
- 在创建约束之后,需要将其添加到作用的view上
- 在添加时要注意目标view需要遵循以下规则:
- 对于两个同层级view之间的约束关系,添加到它们的父view上
- 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
- 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
- 对于两个同层级view之间的约束关系,添加到它们的父view上
4.VFL语言
示例
H:[cancelButton(72)]-12-[acceptButton(50)]
canelButton宽72,acceptButton宽50,它们之间间距12H:[wideView(>=60@700)]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)V:[redBox][yellowBox(==redBox)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBoxH:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
VFL的使用
- 使用VFL来创建约束数组
/ + (NSArray )constraintsWithVisualFormat:(NSString )format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary )metrics views:(NSDictionary )views;
format :VFL语句
opts :约束类型(设置对齐方式,不用的话传kNilOptions)
metrics :VFL语句中用到的具体数值
views :VFL语句中用到的控件 - 创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义
NSDictionaryOfVariableBindings(…)
- 使用VFL来创建约束数组
实例
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
// 不要将AutoresizingMask转为Autolayout的约束
blueView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueView];
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
// 不要将AutoresizingMask转为Autolayout的约束
redView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redView];
// 间距
NSNumber *margin = @20;
// 添加水平方向的约束
NSString *vfl = @"H:|-margin-[blueView]-margin-[redView(==blueView)]-margin-|";
NSDictionary *views = NSDictionaryOfVariableBindings(blueView, redView);
NSDictionary *mertrics = NSDictionaryOfVariableBindings(margin);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:mertrics views:views];
[self.view addConstraints:constraints];
// 添加竖直方向的间距
NSNumber *height = @40;
NSString *vfl2 = @"V:[blueView(height)]-margin-|";
NSDictionary *mertrics2 = NSDictionaryOfVariableBindings(margin, height);
NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:kNilOptions metrics:mertrics2 views:views];
[self.view addConstraints:constraints2];
/**
// 添加红色剩余的约束
NSLayoutConstraint *redContraint1 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
NSLayoutConstraint *redContraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
[self.view addConstraint:redContraint1];
[self.view addConstraint:redContraint2];
*/
5.注意
- 有了Autolayout的UILabel
- 在没有Autolayout之前,UILabel的文字内容总是居中显示,导致顶部和底部会有一大片空缺区域
- 有Autolayout之后,UILabel的bounds默认会自动包住所有的文字内容,顶部和底部不再会有空缺区域
- 在没有Autolayout之前,UILabel的文字内容总是居中显示,导致顶部和底部会有一大片空缺区域
基于Autolayout的动画
- 在修改了约束之后,只要执行下面代码,就能做动画效果
[UIView animateWithDuration:1.0 animations:^{ [添加了约束的view layoutIfNeeded]; }];
- 在修改了约束之后,只要执行下面代码,就能做动画效果