内容简介:有层级关系.png3.对于有层次关系的两个View之间的约束关系,添加到层次较高的父View上。
1.简介
-
1.在以前的iOS代码中是如何设置布局UI界面的?
经常编写大量的坐标计算代码,为了保证在3.5 inch和4.0 inch屏幕上都能有完美的UI界面效果,有时还需要分别为2种屏幕编写不同的坐标计算代码(即传说中的“屏幕适配”)。
-
2.什么是AutoLayout?
AutoLayout是一种自动布局技术,专门用来布局UI界面。AutoLayout自iOS6开始引入,由于xcode4的不给力,当时并没有得到很大的推广。自iOS7开始,AutoLayout的开发效率得到很大的提升,苹果官方也推荐开发者尽量使用AutoLayout来进行UI布局。AutoLayout能够很轻松的解决屏幕适配的问题。
-
3.Autoresizing
在AutoLayout之前,有Autoresizing可以做屏幕适配,但是它局限性较大,很多工作无法完成,相比之下,AutoLayout的功能比Autoresizing强大得多。
2.代码实现AutoLayout
代码实现AutoLayout要注意的点:
1.要先禁止视图的autoresizing功能,视图的下列属性设置为NO:
view.translatesAutoresizingMaskIntoConstraints = NO;
2.添加约束之前,一定保证相关控件都已经添加到各自的父视图上。
3.不再需要为视图设置frame。
代码实现AutoLayout的步骤如下:
1.创建一个NSLayoutConstraint类的实例对象作为具体的约束对象。
1.将这个具体的约束对象添加到对应的视图上去。
1.创建一个NSLayoutConstraint类的实例对象作为具体的约束对象
NSLayoutConstraint类创建具体的约束对象有两种方法:
+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c; + (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
我们先来看第一种方法,第二种方法我们在后面再讲。
+ (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
这个方法创建了一个约束对象,这个约束对象定义了View1的attribute1属性和View2的attribute2属性之间的关系。他们之间有这样的一个线性等式的关系:
item1.attribute1 = multiplier × item2.attribute2 + constant
-
view1
就是约束左边的视图,也就是上面核心等式中的item1
-
attr1
上面核心等式左边的视图的属性,它是NSLayoutAttribute的枚举类型。
NSLayoutAttribute:
typedef NS_ENUM(NSInteger, NSLayoutAttribute) { NSLayoutAttributeLeft = 1, NSLayoutAttributeRight, NSLayoutAttributeTop, NSLayoutAttributeBottom, NSLayoutAttributeLeading, NSLayoutAttributeTrailing, NSLayoutAttributeWidth, NSLayoutAttributeHeight, NSLayoutAttributeCenterX, NSLayoutAttributeCenterY, NSLayoutAttributeLastBaseline, NSLayoutAttributeBaseline NS_SWIFT_UNAVAILABLE("Use 'lastBaseline' instead") = NSLayoutAttributeLastBaseline, NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0), NSLayoutAttributeNotAnAttribute = 0};
-
relation
relation指的是左边的约束和右边的约束之间的关系,左边和右边的云总共有三种关系,即=,>=,<=。所以relation也是一个枚举值:
typedef NS_ENUM(NSInteger, NSLayoutRelation) { NSLayoutRelationLessThanOrEqual = -1,//=};
-
view2
约束右边的视图
-
attr2
约束右边的视图的属性,和attr1一样是枚举值。
-
multiplier
这个就是上面的核心等式中的multiplier,就是乘的倍数。
-
c
就是乘的倍数后面加上的一个常量
2.将这个具体的约束对象添加到对应的视图上去
在添加约束后,要将它作用到对应的view上。
在添加到view上时要遵循以下规则:
-
1.对于两个同层级View之间的约束关系,添加到它们的父视图上。
相同层级.png
2.对于两个不同层级View之间的约束关系,添加到它们最近的共同父View上。
有层级关系.png
3.对于有层次关系的两个View之间的约束关系,添加到层次较高的父View上。
有层级关系.png
3.示例Demo
-
1.创建一个红色的视图和一个蓝色的视图
红色视图和蓝色视图等宽,为100
红色视图和蓝色视图等高,为50
红色视图和蓝色视图在同一水平线上,红色视图在前,红色视图距离左边界为50,蓝色视图距离右边界为50
红色视图和蓝色视图在垂直方向上距离边界的距离都是50。
代码:
self.redview = [[UIView alloc] init]; _redview.backgroundColor = [UIColor redColor]; _redview.translatesAutoresizingMaskIntoConstraints = NO; self.blueview = [[UIView alloc] init]; _blueview.backgroundColor = [UIColor blueColor]; _blueview.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:_redview]; [self.view addSubview:_blueview]; //redview在垂直方向上距离边界为50 NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:50]; //设置redview的宽 NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1 constant:100]; //设置reaview的高 NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1 constant:50]; //设置blueview在垂直高度上和redview等高 NSLayoutConstraint *constraint4 = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_redview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]; //设置blueview和redview等宽 NSLayoutConstraint *constraint5 = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_redview attribute:NSLayoutAttributeWidth multiplier:1 constant:0]; //设置blueview和redview等高 NSLayoutConstraint *constraint6 = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_redview attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; //redview距离左边界为50 NSLayoutConstraint *constraint7 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeading multiplier:1 constant:50]; //blueview距离右边界为50 NSLayoutConstraint *constraint8 = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailing multiplier:1 constant:-50]; [self.view addConstraint:constraint1]; [self.view addConstraint:constraint2]; [self.view addConstraint:constraint3]; [self.view addConstraint:constraint4]; [self.view addConstraint:constraint5]; [self.view addConstraint:constraint6]; [self.view addConstraint:constraint7]; [self.view addConstraint:constraint8];
这段代码看起来比较复杂,当然我们这里也是为了用AutoLayout而用,后面还有更加简便的方法。
-
2.创建一个红色视图和一个蓝色视图
红色视图和蓝色视图的右边界对齐
蓝色视图的宽度是红色视图的宽度的一半
红色视图居中对齐
红色视图在上,蓝色视图在下
代码:
self.redview = [[UIView alloc] init]; _redview.backgroundColor = [UIColor redColor]; _redview.translatesAutoresizingMaskIntoConstraints = NO; self.blueview = [[UIView alloc] init]; _blueview.backgroundColor = [UIColor blueColor]; _blueview.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:_redview]; [self.view addSubview:_blueview]; //redview在垂直方向上距离边界为50 NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:50]; //设置redview的宽 NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1 constant:200]; //设置reaview的高 NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeWidth multiplier:1 constant:50]; //设置readview居中 NSLayoutConstraint *constraint4 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]; //设置blueview宽度是redview的0.5倍 NSLayoutConstraint *constraint5 = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_redview attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]; //设置blueview和redview等高 NSLayoutConstraint *constraint6 = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_redview attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; //redview和blueview的右边界对齐 NSLayoutConstraint *constraint7 = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:_blueview attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]; //blueview顶部距离redview为50 NSLayoutConstraint *constraint8 = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_redview attribute:NSLayoutAttributeBottom multiplier:1 constant:50]; [self.view addConstraint:constraint1]; [self.view addConstraint:constraint2]; [self.view addConstraint:constraint3]; [self.view addConstraint:constraint4]; [self.view addConstraint:constraint5]; [self.view addConstraint:constraint6]; [self.view addConstraint:constraint7]; [self.view addConstraint:constraint8];
运行结果:
结果.png
4.VFL语言
VFL全称是Visual Format Language,翻译过来是“可视化格式语言”
VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言
VFL语法:
-
H
水平方向的约束 -
V:
垂直方向的约束 -
|
边界 -
[]
方括号里面是视图 -
()
圆括号里面是数值 -
== , >=,<=
表示数值的大小关系
实例:
-
H:|-50-[button]-50-|
表达的就是button这个控件距离左边界的距离是50,距离右边界的距离是50。
2.H:|-20-[button(50)]
表示button这个控件距离左边界的距离是20且button宽度是50。
3.V:[button(40)]-20-|
表示button这个控件的高度是40,且其距离下边界的距离是20
4.V:[redview]-[yellowview(==redview)]
在垂直方向上,首先有一个视图redview,然后在其下方,紧挨着有一个视图yellowview,并且redview和yellowview的高度一致
使用VFL来创建约束数组
在第二部分 代码实现AutoLayout 中提到过NSLayoutConstraint类创建具体的约束对象有两种方法,在那部分我们只讲了第一种方法,还有第二种方法我们没有讲。
第二种方法就是:
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;
这种方法就是使用VFL语法来创建一组约束对象。这个方法返回的是一个数组,这个数组中的对象都是NSLayoutConstraint类的实例对象。
-
format
VFL描述语句
-
opts
它是NSLayoutFormatOptions的枚举值
typedef NS_OPTIONS(NSUInteger, NSLayoutFormatOptions) { NSLayoutFormatAlignAllLeft = (1 << NSLayoutAttributeLeft), NSLayoutFormatAlignAllRight = (1 << NSLayoutAttributeRight), NSLayoutFormatAlignAllTop = (1 << NSLayoutAttributeTop), NSLayoutFormatAlignAllBottom = (1 << NSLayoutAttributeBottom), NSLayoutFormatAlignAllLeading = (1 << NSLayoutAttributeLeading), NSLayoutFormatAlignAllTrailing = (1 << NSLayoutAttributeTrailing), NSLayoutFormatAlignAllCenterX = (1 << NSLayoutAttributeCenterX), NSLayoutFormatAlignAllCenterY = (1 << NSLayoutAttributeCenterY), NSLayoutFormatAlignAllLastBaseline = (1 << NSLayoutAttributeLastBaseline), NSLayoutFormatAlignAllBaseline NS_SWIFT_UNAVAILABLE("Use 'alignAllLastBaseline' instead") = NSLayoutFormatAlignAllLastBaseline, NSLayoutFormatAlignAllFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0) = (1 << NSLayoutAttributeFirstBaseline), NSLayoutFormatAlignmentMask = 0xFFFF, /* choose only one of these three */ NSLayoutFormatDirectionLeadingToTrailing = 0 << 16, // default NSLayoutFormatDirectionLeftToRight = 1 << 16, NSLayoutFormatDirectionRightToLeft = 2 << 16, NSLayoutFormatDirectionMask = 0x3 << 16, /* choose only one spacing format */ NSLayoutFormatSpacingEdgeToEdge API_AVAILABLE(ios(11.0),tvos(11.0)) = 0 << 19, // default NSLayoutFormatSpacingBaselineToBaseline API_AVAILABLE(ios(11.0),tvos(11.0)) = 1 << 19, NSLayoutFormatSpacingMask API_AVAILABLE(ios(11.0),tvos(11.0)) = 0x1 << 19, };
比如说现在的VFL语句是 @"H:|-50-[redview]-20-[blueview(==redview)]-50-|"
,而NSLayoutFormatOptions枚举类型是 NSLayoutFormatAlignAllCenterY
,那么表达的意思就是在水平方向上redview距离左边界是50,blueview距离右边界是50,redview和blueview之间的水平距离是20,并且, redview和blueview的垂直高度一致 。 opts在这里的作用就是添加一个约束 。
-
metrics
这是一个字典类型的参数,这个字典的键必须是出现在VFL语句中的常量字符串,而值则是我们想要这个常量字符串想要代表的值。
-
views
这是一个字典类型,表示VFL语句中用到的控件。比如说我们在VFL语句中为了简便起见,使用rv代表_redview,使用bv代表_blueview,那么views可以这样写:@{@"rv":_redview,@"bv":_blueview}
使用Demo
-
1.创建一个红色的视图和一个蓝色的视图
红色视图和蓝色视图等宽等高
红色视图和蓝色视图在垂直高度上相等
红色视图和蓝色视图之间的水平距离为20
红色视图距离左边界的距离为50,蓝色视图距离右边界的距离为50
代码:
self.redview = [[UIView alloc] init]; _redview.backgroundColor = [UIColor redColor]; _redview.translatesAutoresizingMaskIntoConstraints = NO; self.blueview = [[UIView alloc] init]; _blueview.backgroundColor = [UIColor blueColor]; _blueview.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:_redview]; [self.view addSubview:_blueview]; //设置redview距离左边界为50,blueview距离右边界为50,redview和blueview之间的水平距离为20,且redview和blueview等宽,并且redview和blueview在垂直高度上等高,怎么样?是不是一次性约束了很多条件? NSArray *consts1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[redview]-20-[blueview(==redview)]-50-|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:@{@"redview":_redview,@"blueview":_blueview}]; //垂直方向上,redView距离上边界为100,且redview的高度是80 NSArray *consts2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[redview(80)]" options:0 metrics:nil views:@{@"redview":_redview}]; //设置redview和blueview的头部在同一高度 NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_redview attribute:NSLayoutAttributeTop relatedBy:0 toItem:_blueview attribute:NSLayoutAttributeTop multiplier:1 constant:0]; [self.view addConstraints:consts1]; [self.view addConstraints:consts2]; [self.view addConstraint:constraint];
运行效果:
-
2.创建一个红色的视图和一个蓝色的视图
红色视图和蓝色视图的右边界对齐
红色视图的宽度是蓝色视图的两倍
红色视图在水平方向上居中
红色视图在蓝色视图的上面,红色视图和蓝色视图紧挨着
代码:
self.redview = [[UIView alloc] init]; _redview.backgroundColor = [UIColor redColor]; _redview.translatesAutoresizingMaskIntoConstraints = NO; self.blueview = [[UIView alloc] init]; _blueview.backgroundColor = [UIColor blueColor]; _blueview.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:_redview]; [self.view addSubview:_blueview]; //水平方向上,设置redview距离右边界为50,距离左边界为50 NSArray *consts1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[redview]-50-|" options:0 metrics:nil views:@{@"redview":_redview}]; //垂直方向上,redView距离上边界为100,且redview的高度是80,下面紧挨着blueview,且redview和blueview右边界对齐 NSArray *consts2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[redview(80)][blueview(==redview)]" options:NSLayoutFormatAlignAllRight metrics:nil views:@{@"redview":_redview, @"blueview":_blueview}]; //设置blueview的宽是redview的一半 NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:_blueview attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_redview attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]; [self.view addConstraints:consts1]; [self.view addConstraints:consts2]; [self.view addConstraint:constraint];
运行效果:
结果2.png
通过代码量我们能够清晰的看到,使用VFL来进行约束会轻松很多。
作者:雪山飞狐_91ae
链接:https://www.jianshu.com/p/90811f80dd1e
以上所述就是小编给大家介绍的《iOS使用代码进行AutoLayout自动布局》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 一个UI布局框架,以最少的代码实现UI设置及布局控制
- Android 代码布局 —— 从入门到放弃(一)
- 最简单的代码,让 WPF 支持响应式布局
- iOS狂暴之路–两种布局方式操作详解(xib文件和代码编写)
- css经典布局系列三——三列布局(圣杯布局、双飞翼布局)
- 四种方法实现──三栏布局(圣杯布局、双飞翼布局)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java程序设计与应用开发
於东军 / 清华大学出版社 / 2005-3 / 27.00元
本书作为Java程序的入门与应用教材,共分为3部分:第一部分讲解Java程序设计的基础知识,包括Java基本编程语言、面向对象设计思想、类、对象、接口以及异常处理。第二部分讲解Java程序设计的高级知识,包括:GUI编程、套接口编程、I/O系统、数据库访问以及多线程编程。第三部分详细分析一个实际项目的开发过程,包括系统分析及功能实现。在项目实例中综合应用第一、二部分的Java知识,能够帮助读者进一......一起来看看 《Java程序设计与应用开发》 这本书的介绍吧!