iOS的屏幕适配之Autoresizing、Autolayout、VFL、Masonry
来源:互联网 发布:淘宝店一件代发赚钱么 编辑:程序博客网 时间:2024/05/22 05:14
一、苹果产品的发行
二、设备的分辨率
三、屏幕适配
- iPhone4S之前没有屏幕适配,因为屏幕尺寸不变,全部用frame、bounds、center进行布局。
- iphone5之后才开始有屏幕适配。
四、Autoresizing
- iPad的出现和iPhone横屏的出现,出现Autoresizing技术
- Autoresizing让横竖屏适配相对于用frame、bounds、center进行布局简单
- 使用Autoresizing的前提是:关闭Autolayout功能;因为有些功能重复
- 局限性
- 只能解决子控件跟父控件的相对关系问题
- 不能解决兄弟控件的相对关系问题 - 当控件的的autoresizesSubviews是YES时,(默认是YES),那么UIView对象的子控件会根据子控件自身的autoresizingMask属性值来自动适应与其父控件之间的位置和大小
storyboard或xib下使用Autoresizing,宽高和宽度的自动调整:实线代表选中,左右上下间距的自动调整:虚线代表选中
- 纯代码使用Autoresizing
---------- UIViewAutoresizing类型,有两个尖号<<代表可以复选,复选用竖杠隔开typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) { //不自动调整 UIViewAutoresizingNone = 0, //自动按与父控件比例调整与父控件左边的距离,且与父控件右边的距离不变 UIViewAutoresizingFlexibleLeftMargin = 1 << 0, //自动按与父控件比例调整与父控件的右边距离,且与父控件左边的距离不变 UIViewAutoresizingFlexibleRightMargin = 1 << 2, //自动按与父控件比例调整与父控件的顶部距离,且与父控件底部的距离不变 UIViewAutoresizingFlexibleTopMargin = 1 << 3, //自动按与父控件比例调整与父控件的底部距离,且与父控件顶部的距离不变 UIViewAutoresizingFlexibleBottomMargin = 1 << 5 //自动与父控件按比例调整宽度 UIViewAutoresizingFlexibleWidth = 1 << 1, //自动与父控件按比例调整高度 UIViewAutoresizingFlexibleHeight = 1 << 4,};---------- Autoresizing的使用 #import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //创建控件,做为父控件 UIView *viewSuper = [[UIView alloc] initWithFrame:CGRectMake(40, 50, 200, 200)]; viewSuper.backgroundColor = [UIColor greenColor]; [self.view addSubview:viewSuper]; //创建控件,做为子控件 UIView *viewSub = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 50, 100)]; viewSub.backgroundColor = [UIColor orangeColor]; [viewSuper addSubview:viewSub]; //autoresizesSubviews的默认值为YES //当值为NO时,不会根据子控件的autoresizingMask属性值来自动调整 //viewSuper.autoresizesSubviews = NO; //自动按照比例调整与父控件的左间距和自动按比例调整宽度 viewSub.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth;}//随机改变父控件的宽高,测试调整效果- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //arc4random_uniform()是取随机数 CGFloat w = 200 + arc4random_uniform(100); CGFloat h = 200 + arc4random_uniform(100); [[self.view.subviews lastObject] setFrame:CGRectMake(40, 40, w, h)];}@end
五、Autolayout
(一).Autolayout的2个核心概念
1.参照:参照是指一个约束是根据那个控件来计算约束的,做为参照的控件位置和尺寸大小必须明确
2.约束:约束相当于控件的Frame,用来明确控件所处的位置和控件的的尺寸大小
(二).Autolayout核心计算公式
约束的计算方法:obj1.property =(<=或>=)(obj2.property * multiplier)+ constant
解析:
=: 等号可以根据需求改为:小于等于或大于等于
obj1:控件
property:左边线,右边线,垂直中心线,上边线,下边线,水平中心线,高度,宽度等的约束值
multiplier:倍数
constant:偏移量
(二).注意:
1.约束的本质:用来明确控件所处的位置和控件的的尺寸大小
2.约束和Frame类似,Frame也是用来确定位置和尺寸的大小
3.给一个控件加约束,要么不加,要么加全了;只要给控件添加一个约束,就要加全必要约束,要让控件明确的知道它自己的尺寸和所处的位置,苹果鼓励开发者尽量用Autolayout,忘掉Frame
4.Updata Frames:设置约束后更新Frame;如果约束不全,更新之后控件就会找不到
5.控件UILable很特殊,只约束它的位置,不约束尺寸大小,系统会自动添加宽度和高度约束,这个特性可以用于设置lable的宽度或高度随内容的变化而变化
(三).storyboard和xib下的设置
1.Autolayout的警告和错误
(1).警告
控件的frame不匹配所添加的约束
比如:约束控件的宽度为100, 而控件现在的宽度是110
(2).错误
a.缺乏必要的约束
比如:只约束了宽度和高度, 没有约束具体的位置
b.两个约束冲突
比如:1个约束控件的宽度为100, 1个约束控件的宽度为110
2.添加约束时,系统会自动以Top Layout Guide和Bottom Layout Guide两条线做为约束的参照物,这两天线是系统自动创建时就添加的
3.约束的属性面板:可以在这个面板修改约束
4.Constrain to margins:选中就默认在左右两边各加上16个像素
5.更新约束(一)
(1).成功添加就就马上更新
(2.)手动更新
6.拖拽添加约束
(四).代码实现Autolayout
1.实现步骤
(1).先禁止autoresizing功能,设置view的下面属性为NO
view.translatesAutoresizingMaskIntoConstraints = NO;
(2).利用NSLayoutConstraint类创建具体的约束对象
创建约束对象的常用方法:
+(instancetype)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 :常量计算公式:attr1 =(<=或>=) attr2 * multiplier + c**/
(3).添加约束对象到相应的view上
- (void)addConstraint:(NSLayoutConstraint *)constraint;- (void)addConstraints:(NSArray *)constraints;
2.添加约束的规则
(1).对于两个同层级view之间的约束关系,添加到它们的父view上
(2).对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
(3).对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
3.注意
(a).要先禁止autoresizing功能,设置view的translatesAutoresizingMaskIntoConstraints属性为NO;不然系统会自动把Autoresizing的值转换成约束
(b).添加约束之前,一定要保证相关控件都已经在各自的父控件上
(c).不用再给view设置frame
(d).添加约束不要添加错了控件
(e).一般报错原因是:约束冲突或者约束不完整
4.编程举例
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //创建一个蓝色的View,不用设置Frame,设置了可能会起冲突 UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束 blueView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview: blueView]; //创建一个红色的View,不用设置Frame,设置了可能会起冲突 UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束 redView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:redView];#pragma mark - 设置蓝色的约束 //给蓝色View添加约束:顶部距离父控件上边框50像素 NSLayoutConstraint *blueTopLayout = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:50]; [self.view addConstraint:blueTopLayout]; //给蓝色View添加约束:左边距离父控件左边框180像素 NSLayoutConstraint *blueLeftLayout = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:80]; [self.view addConstraint:blueLeftLayout]; //给蓝色View添加约束:宽度为100个像素 NSLayoutConstraint *blueWidthLayout = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100]; [blueView addConstraint:blueWidthLayout]; //给蓝色View添加约束:高度为100个像素 NSLayoutConstraint *blueHeightLayout = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100]; [blueView addConstraint:blueHeightLayout];#pragma mark - 设置红色的约束 //给红色View添加约束:宽度为100个像素 NSLayoutConstraint *redWidthLayout = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100]; //给红色View添加约束:高度为100个像素 NSLayoutConstraint *redHeightLayout = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:100]; //用数组的方式批量添加约束 [redView addConstraints:@[redWidthLayout,redHeightLayout]]; //给红色View添加约束:红色的左边线距离蓝色的右边线距0个像素 NSLayoutConstraint *redLeftLayout = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; //给红色View添加约束:红色的上边线与蓝色的上边线对齐 NSLayoutConstraint *redTopLayout = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; //用数组的方式批量添加约束 [self.view addConstraints: @[redLeftLayout,redTopLayout]];}@end
六、VFL语言
1.VFL全称是Visual Format Language,翻译过来是“可视化格式语言”
2.VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言
3.语法
(1).语法列表
(2).举例
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的边缘)
4.使用VFL语言设置约束的步骤
(1).用VFL语言创建VFL语句,用字符串表示
(2).把VFL语句中包含的数值或控件用字典表示
//创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义NSDictionary *dic = NSDictionaryOfVariableBindings(…);
(3).使用VFL来创建约束数组的常用方法
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;/**解析 format :VFL语句 opts :约束类型,一般写kNilOptions,表示空选项metrics :VFL语句中用到的具体数值 views :VFL语句中用到的控件**/
(4).把约束数组添加到对应的控件中
- (void)addConstraints:(NSArray *)constraints;
5.代码举例
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //创建一个蓝色的View,不用设置Frame UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束 blueView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview: blueView]; //水平方向下:控件blueView的宽度等于100像素,左右边距为默认一个小间距 NSString *vfl1 = @"H:|-[blueView(==100)]-|"; NSDictionary *ditViews1 = NSDictionaryOfVariableBindings(blueView); NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl1 options:kNilOptions metrics:nil views:ditViews1]; [self.view addConstraints:constraints]; //垂直方向下:控件blueView距左边距50个像素,高度等于100像素,右边距为默认一个小间距 NSNumber *n = @100; NSString *vfl2 = @"V:|-50-[blueView(==n)]-|"; NSDictionary *metrics = NSDictionaryOfVariableBindings(n); NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vfl2 options:kNilOptions metrics:metrics views:ditViews1]; [self.view addConstraints:constraints2];}@end
6.有用到Frmae属性的控件,不用把translatesAutoresizingMaskIntoConstraints属性设置为NO,设置为NO后,Frame将不起作用,值为0
#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //创建一个蓝色的View UIView *blueView = [[UIView alloc] initWithFrame:CGRectMake(100, 50, 200, 200)]; blueView.backgroundColor = [UIColor blueColor]; //如果控件不设置约束,而是直接使用Frame,就不用设置属性为NO blueView.translatesAutoresizingMaskIntoConstraints = YES; [self.view addSubview: blueView]; //创建一个红色的View,不用设置Frame UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; //必须要设置为NO,默认是YES,在YES的时,系统会自动把Autoresizing的值转换成约束 redView.translatesAutoresizingMaskIntoConstraints = NO; [blueView addSubview:redView]; //redView与父控件的左右边距各为一个小间隔 NSString *vflH = @"|-[redView]-|"; NSDictionary *dic = NSDictionaryOfVariableBindings(redView); NSArray *constraints1 = [NSLayoutConstraint constraintsWithVisualFormat:vflH options:kNilOptions metrics:nil views:dic]; [blueView addConstraints:constraints1]; //redView紧贴父控件的上边框,高度为100 NSString *vflV = @"V:|[redView(==100)]"; NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vflV options:kNilOptions metrics:nil views:dic]; [blueView addConstraints:constraints2];}@end
七、Masonry
(一).简介
1.目前最流行的Autolayout第三方框架
2.用优雅的代码方式编写Autolayout
3.省去了苹果官方Autolayout长代码
(二).添加约束的类型
1.尺寸:width\height\size
2.边界:left\leading\right\trailing\top\bottom
3.中心点:center\centerX\centerY
4.边界:edges
(三).添加约束的方法
1.mas_makeConstraints:这个方法只会添加新的约束
2.mas_updateConstraints:这个方法将会覆盖以前的某些特定的约束
3.mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束
(四).注意
1.创建的控件时不用再把控件的translatesAutoresizingMaskIntoConstraints属性设置为NO,框架里已经封装
2.equalTo方法不会对数据进行包装
3.mas_equalTo方法会对参数进行包装
4.multipliedBy表示乘数
5.offset:这个方法代表偏移量,正表示往下或往右移动,负表示往上或往左移动
6.当只对宽高进行约束,不对位置约束时,位置默认在父控件的左上角
7.只要添加了#define MAS_SHORTHAND这个宏,就不用带mas_前缀
8.只要添加了#define MAS_SHORTHAND_GLOBALS这个宏,equalTo就等价于mas_equalTo
9.#define MAS_SHORTHAND 和 #define MAS_SHORTHAND_GLOBALS 一定要添加到#import “Masonry.h”上面,因为Masonry.h里面的代码要用到这两个宏
(五).代码举例
下面代码中,每一个添加约束的方法都可以独立完整的添加约束,可以挨个进行测试
#import "ViewController.h"//define this constant if you want to use Masonry without the 'mas_' prefix#define MAS_SHORTHAND//define this constant if you want to enable auto-boxing for default syntax#define MAS_SHORTHAND_GLOBALS#import "Masonry.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //创建一个红色视图 UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; //mas_makeConstraints:这个方法只会添加新的约束 [redView mas_makeConstraints:^(MASConstraintMaker *make) { //equalTo:这个方法不会对参数进行包装, make.width.equalTo(@100); //mas_equalTo:这个方法会对参数进行包装 make.width.mas_equalTo(100); //offset:这个方法代表偏移量,正表示往下或往右移动,负表示往上或往右移动 make.top.equalTo(self.view).offset(100); make.right.equalTo(self.view.mas_left).offset(200); }]; //mas_updateConstraints:这个方法将会覆盖以前的某些特定的约束 [redView mas_updateConstraints:^(MASConstraintMaker *make) { //size:设置宽和高的约束 make.size.equalTo([NSValue valueWithCGSize:CGSizeMake(50, 50)]); //make.size.mas_equalTo(CGSizeMake(200 , 200)); }]; //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束 [redView mas_remakeConstraints:^(MASConstraintMaker *make) { //redView高等于父控件的0.5倍,在加上10个像素 make.height.equalTo(self.view.mas_height).multipliedBy(0.5).offset(10); //redView宽等于父控件的0.5倍,在减去10个像素 make.width.mas_equalTo(self.view.mas_width).multipliedBy(0.5).offset(-10); }]; //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束 [redView mas_remakeConstraints:^(MASConstraintMaker *make) { //距离父控件四周都是50间距 make.edges.mas_equalTo(self.view).insets(UIEdgeInsetsMake(50, 50, 50, 50)); }]; //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束 [redView mas_remakeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(@150); make.height.mas_equalTo(150); //redView的中心在父控件的中心 make.center.mas_equalTo(self.view).insets(UIEdgeInsetsZero); }]; //mas_remakeConstraints:这个方法会将以前的所有约束删掉,添加新的约束 [redView mas_remakeConstraints:^(MASConstraintMaker *make) { //必须要在文件开头添加 #define MAS_SHORTHAND 和 #define MAS_SHORTHAND_GLOBALS //才能在equalTo中用基本数据类型的数据,宏定义会自动包装基本数据类型的数据 make.width.equalTo(100); make.height.equalTo(100); make.centerX.equalTo(self.view.centerX); make.centerY.equalTo(self.view.centerY); }];}@end
- iOS的屏幕适配之Autoresizing、Autolayout、VFL、Masonry
- 屏幕适配、Autoresizing、Autolayout
- iOS中关于适配的那些事(本篇首要了解autoresizing、autoLayout、VFL;下篇了解第三方适配)
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配--autoResizing autoLayout和sizeClass图文详解
- iOS 屏幕适配,autoResizing autoLayout和sizeClass图文详解
- iOS基础——屏幕适配之autoResizing、autoLayout、sizeClass
- 屏幕适配-----Autoresizing和AutoLayout
- iOS之界面开发屏幕适配Interface Builder、Storyboard、Xib、Nib、AutoSizing、AutoLayout、Masonry
- 自动布局Autoresizing autolayout VFL
- 屏幕适配之-Autoresizing
- AutoLayout代码适配之VFL
- A^B取后三位
- 143. Reorder List
- netbeans快捷键
- Ubuntu Server搭建OpenVPN服务器实战
- 高性能网络服务器编程:为什么linux下epoll是最好,Netty要比NIO.2好?
- iOS的屏幕适配之Autoresizing、Autolayout、VFL、Masonry
- 傅立叶分析导论-2 Basic Properties of Fourier Series
- 为自己而活!
- javascript内存管理介绍
- tomcat导入maven项目运行抛出org.springframework.web.context.ContextLoaderListener not found
- JokeClient-Swift 仿写学习
- 【Android】View绘制
- 荷包金融怎么升级?
- <设计模式一>普通工厂模式