屏幕适配Autoresizing 屏幕适配的发展简史
iPhone3GS\iPhone4
没有屏幕适配可言
全部用frame、bounds、center进行布局
很多这样的现象:坐标值、宽度高度值全部写死
1 2 UIButton *btn1 = [[UIButton alloc] init];btn1.frame = CGRectMake (0 , 0 , 320 - b, 480 - c);
iPad出现、iPhone横屏
出现Autoresizing技术
让横竖屏适配相对简单
让子控件可以跟随父控件的行为自动发生相应的变化
前提是:关闭Autolayout功能
局限性
只能解决子控件跟父控件的相对关系问题
不能解决兄弟控件的相对关系问题
iOS 6.0(Xcode4)开始
出现了Autolayout技术
从Xcode5.0(iOS 7.0)开始,开始流行Autolayout
设备分辨率 Autoresizing代码实现: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #import "ViewController.h" @interface ViewController ()@property (nonatomic , strong ) UIView *blueView;@end @implementation ViewController - (void )viewDidLoad { [super viewDidLoad]; 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.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth ; [blueView addSubview:redView]; } - (void )touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { CGFloat w = 200 + arc4random_uniform(100 ); CGFloat h = 200 + arc4random_uniform(100 ); self .blueView.frame = CGRectMake (0 , 0 , w, h); } @end
UIView中autoresizingMask属性值的含义:
屏幕适配Autolayout
Autolayout中的错误和警告
警告(黄色) 控件的frame不匹配所添加的约束, 比如 比如约束控件的宽度为100, 而控件现在的宽度是110
错误(红色) 缺乏必要的约束, 比如 只约束了宽度和高度, 没有约束具体的位置
两个约束冲突, 比如 1个约束控件的宽度为100, 1个约束控件的宽度为110
Autolayout代码实现
代码实现Autolayout的步骤
利用NSLayoutConstraint类创建具体的约束对象
添加约束对象到相应的view上
1 2 - (void )addConstraint:(NSLayoutConstraint *)constraint; - (void )addConstraints:(NSArray *)constraints;
代码实现Autolayout的注意点
要先禁止autoresizing功能,设置view的下面属性为NO
1 2 3 4 5 6 7 view.translatesAutoresizingMaskIntoConstraints = NO ;
添加约束之前,一定要保证相关控件都已经在各自的父控件上
一个NSLayoutConstraint对象就代表一个约束
** 约束要添加到约束所关联的父控件上**
创建约束对象的常用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +(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 :常量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 - (void )viewDidLoad { [super viewDidLoad]; UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO ; [self .view addSubview:blueView]; UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; redView.translatesAutoresizingMaskIntoConstraints = NO ; [self .view addSubview:redView]; NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:40 ]; [blueView addConstraint:heightConstraint]; NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20 ]; [self .view addConstraint:leftConstraint]; NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20 ]; [self .view addConstraint:rightConstraint]; NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeTop multiplier:1.0 constant:20 ]; [self .view addConstraint:topConstraint]; NSLayoutConstraint *heightConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0 ]; [self .view addConstraint:heightConstraint2]; NSLayoutConstraint *leftConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0 ]; [self .view addConstraint:leftConstraint2]; NSLayoutConstraint *topConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20 ]; [self .view addConstraint:topConstraint2]; NSLayoutConstraint *rightConstraint2 = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0 ]; [self .view addConstraint:rightConstraint2]; } - (void )test2 { UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO ; [self .view addSubview:blueView]; NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0 ]; [self .view addConstraint:widthConstraint]; NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeHeight multiplier:0.5 constant:0 ]; [self .view addConstraint:heightConstraint]; NSLayoutConstraint *centerXConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0 ]; [self .view addConstraint:centerXConstraint]; NSLayoutConstraint *centerYConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0 ]; [self .view addConstraint:centerYConstraint]; } - (void )test1 { UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO ; [self .view addSubview:blueView]; NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100 ]; [blueView addConstraint:widthConstraint]; NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100 ]; [blueView addConstraint:heightConstraint]; NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-10 ]; [self .view addConstraint:rightConstraint]; NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self .view attribute:NSLayoutAttributeTop multiplier:1.0 constant:10 ]; [self .view addConstraint:topConstraint]; } @end
自动布局的核心计算公式
obj1.property1 =(obj2.property2 * multiplier)+ constant value
VFL语言
VFL语言实例和代码实现
H:[cancelButton(72)]-12-[acceptButton(50)]
canelButton宽72,acceptButton宽50,它们之间间距12
H:[wideView(>=60@700)]
wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)
V:[redBox][yellowBox(==redBox)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox
H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)
使用VFL来创建约束数组 1 2 3 4 5 6 7 8 9 + (NSArray *)constraintsWithVisualFormat:(NSString *) format options:(NSLayoutFormatOptions )opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views; *format :VFL语句 *opts :约束类型(顶部对齐 底部对齐等等) *metrics :VFL语句中用到的具体数值 *views :VFL语句中用到的控件
创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义
1 NSDictionaryOfVariableBindings (...)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 @implementation ViewController - (void )viewDidLoad { [super viewDidLoad]; UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO ; [self .view addSubview:blueView]; UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; 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]; } - (void )test2 { UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO ; [self .view addSubview:blueView]; NSNumber *margin = @20 ; NSString *vfl = @"H:|-margin-[blueView]-margin-|" ; NSDictionary *views = NSDictionaryOfVariableBindings (blueView); NSDictionary *mertrics = NSDictionaryOfVariableBindings (margin); NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:mertrics views:views]; [self .view addConstraints:constraints]; NSNumber *height = @40 ; NSString *vfl2 = @"V:|-margin-[blueView(height)]" ; NSDictionary *mertrics2 = NSDictionaryOfVariableBindings (margin, height); NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:kNilOptions metrics:mertrics2 views:views]; [self .view addConstraints:constraints2]; } - (void )test1 { UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; blueView.translatesAutoresizingMaskIntoConstraints = NO ; [self .view addSubview:blueView]; NSString *vfl = @"H:|-20-[blueView]-20-|" ; NSDictionary *views = @{@"blueView" : blueView}; NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl options:kNilOptions metrics:nil views:views]; [self .view addConstraints:constraints]; NSString *vfl2 = @"V:|-20-[blueView(40)]" ; NSDictionary *views2 = @{@"blueView" : blueView}; NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:kNilOptions metrics:nil views:views2]; [self .view addConstraints:constraints2]; } @end
VFL语言不能实现的 Masonry
目前最流行的Autolayout第三方框架
用优雅的代码方式编写Autolayout
省去了苹果官方恶心的Autolayout代码
大大提高了开发效率
点击此处获取框架地址
1 2 3 4 5 6 #define MAS_SHORTHAND #define MAS_SHORTHAND_GLOBALS #import "Masonry.h"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [view makeConstraints:^(MASConstraintMaker *make) { }]; [view remakeConstraints:^(MASConstraintMaker *make) { }]; [view updateConstraints:^(MASConstraintMaker *make) { }];
1 2 3 4 1. 尺寸:width\height\size2. 边界:left\leading\right\trailing\top\bottom3. 中心点:center\centerX\centerY4. 边界:edges