AI智能
改变未来

NSLayoutContraint的使用

一、介绍

说起自动布局,什么masonry或者sd_autolayout等三方库,都是基于原生的NSLayoutContraint来写的,所以有必要知道NSLayoutContraint这个东西。

二、发展史

1、屏幕适配发展的路线:

1)纯代码计算frame(最早是通过计算frame实现布局)
2)autoresizing(仅适用于约束父子控件之间的关系)
3)AutoLayout(iOS6/2012年、iPhone5被引入,比autoresizing更加高级,旨在替代autoresizing,可以设置任何控件之间的关系)
4)sizeClass(iOS8出现,用于解决越来越多的屏幕尺寸的适配问题)。

2、为什么总是在变换屏幕布局的方式?在iPhone3gs时代,手机的屏幕尺寸有且只有一种,也就是3.5英寸。开发app的时候,根本不用考虑同一个视图在不同尺寸的屏幕上显示的问题。iOS开发者完全可以**用纯代码的方式**把一个控件的frame写死。而后来随着苹果公司的不断推出新机型,随着屏幕的尺寸变大和布局时候的复杂程度越来越大,在使用写死frame的方法是满足不了需求的,所以最后苹果公司为了开发者能够更好的工作就逐渐推出了autoresizing,AutoLayout(iOS6.0),sizeClass(iOS).

三、AutoresizingXcode5之后,新建的项目默认使用AutoLayout。Autoresizing默认不启用,我们可以去掉use Auto Layout,Use Size Classes前面的对勾来启用Autoresizing,如下图:
UIView的autoresizesSubviews是YES时(默认是YES), 那么在其中的子view会根据它自身的autoresizingMask属性来自动适应其与superView之间的位置和大小。通俗易懂的话语来讲就是:当父视图被拉伸的时候,子视图能够适配父视图的新大小。其原理是,子视图有一个masks,用于指定与父视图上下左右边缘的距离,以及自身宽高的关系。比如,指定子视图的右边缘紧跟着父视图的右边缘,那么父视图变大之后,子视图还是贴在父视图的右边。这在大部分简单布局情况下非常有效

四、Autolayout

1、AutolayoutContraint

AutoLayout是从IOS 6开始苹果引入来取代autoresizing的新的布局技术,该技术有三种设置方式,在说三种设置方式前,我们先简单的说一下autolayout能够设置哪些行为。
1)视图的大小(即视图的绝对大小)。2)视图的位置(视图相对于父视图或者兄弟视图的位置)。
3)视图的对齐方式(相对于父视图或者相对于兄弟视图)。
可以看到autolayout相比autoresizing技术来说要灵活的多,该技术有很多布局的约束设置。这次主要讲的用代码来设置AutoLayout,必须要注意的是在使用 Auto Layout 时,首先需要将视图的 setTranslatesAutoresizingMaskIntoConstraints 属性设置为 NO。这个属性默认为 YES。当它为 YES 时,运行时系统会自动将 Autoresizing Mask 转换为 Auto Layout 的约束,这些约束很有可能会和我们自己添加的产生冲突。代码向我们需要添加autoLayout视图使用该方法:

+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c

#pragma mark -methodOne- (void)methodOne{_redV = [[UIView alloc] initWithFrame:CGRectZero];_redV.backgroundColor = [UIColor redColor];[self.view addSubview:_redV];//为了防止constraint和view的zutoresizing属性冲突,我们需要设置view的属性self.redV.translatesAutoresizingMaskIntoConstraints = NO;/*@param item1 指定需要添加约束的视图一@param attribute 指定视图一需要约束的属性@param relatedBy 指定个视图一和视图二添加约束的关系@param item2 指定视图一依赖关系的视图二,可为nil@param attribute 指定视图一所依赖的视图二的属性,若view2 = nil,该属性设置NSLayoutAttributeNotAnAttribute@param multiplier 系数 情况一:设置A视图的高度 = A视图高度 * multiplier + constant;此时才会起作用;情况二:设置A视图和其他视图的关系或 toItem=nil,multiplier设置不等于0即可,若等于0会crash;@param*///设置redView的宽 = 100.fNSLayoutConstraint * readViewW = [NSLayoutConstraint constraintWithItem:self.redVattribute:NSLayoutAttributeWidthrelatedBy:NSLayoutRelationEqualtoItem:nilattribute:NSLayoutAttributeNotAnAttributemultiplier:1.fconstant:100.f];//设置readView的高 = 100.fNSLayoutConstraint * readViewH = [NSLayoutConstraint constraintWithItem:self.redVattribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:nilattribute:NSLayoutAttributeNotAnAttributemultiplier:1.0constant:100.f];//设置readView的左 = 20.fNSLayoutConstraint * readViewL = [NSLayoutConstraint constraintWithItem:self.redVattribute:NSLayoutAttributeLeadingrelatedBy:NSLayoutRelationEqualtoItem:self.viewattribute:NSLayoutAttributeLeadingmultiplier:1.fconstant:20.f];//设置readView的上 = 50.fNSLayoutConstraint * readViewT = [NSLayoutConstraint constraintWithItem:self.redVattribute:NSLayoutAttributeToprelatedBy:NSLayoutRelationEqualtoItem:self.viewattribute:NSLayoutAttributeTopmultiplier:1.fconstant:50.f];//添加约束到视图[self.view addConstraint:readViewW];[self.view addConstraint:readViewH];[self.view addConstraint:readViewL];[self.view addConstraint:readViewT];}

2、VFL 语言1)什么是 VFL 语言:
VFL(Visual Format Language),“可视化格式语言”。
VFL是苹果公司为了简化autolayout的编码而推出的抽象语言2)基本语法表

功能 表达式
水平方向 H:
垂直方向 V:
Views [view]
关系 >=,==,<=
SuperView |
空间,间隙 –
优先级 @value

3)具体的方法

+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;

4)具体说一下参数

format 就是填写刚刚咱们学习的 VFL 语言,注意,这里是需要将 VFL语言写成字符串传递进去,所以这一步很容易出错,错了也不会有报错提示,需要咱们平日里多加练习与锻炼才能很好的避免一些错误

typedef NS_ENUM(NSInteger, NSLayoutRelation) {NSLayoutRelationLessThanOrEqual = -1,          //小于等于NSLayoutRelationEqual = 0,                     //等于NSLayoutRelationGreaterThanOrEqual = 1,        //大于等于};typedef NS_ENUM(NSInteger, NSLayoutAttribute) {NSLayoutAttributeLeft = 1,                     //左侧NSLayoutAttributeRight,                        //右侧NSLayoutAttributeTop,                          //上方NSLayoutAttributeBottom,                       //下方NSLayoutAttributeLeading,                      //首部NSLayoutAttributeTrailing,                     //尾部NSLayoutAttributeWidth,                        //宽度NSLayoutAttributeHeight,                       //高度NSLayoutAttributeCenterX,                      //X轴中心NSLayoutAttributeCenterY,                      //Y轴中心NSLayoutAttributeBaseline,                     //文本底标线NSLayoutAttributeNotAnAttribute = 0            //没有属性};NSLayoutAttributeLeft/NSLayoutAttributeRight 和NSLayoutAttributeLeading/NSLayoutAttributeTrailing的区别是left/right永远是指左右,而leading/trailing在某些从右至左习惯的地区会变成,leading是右边,trailing是左边。

metrics 表示使用到的度量数组,你可以把一些VFL 语言用的值定义在一个字典里面例如创建一个字典NSDictionary *metres = @{@\"leftArglin\":@20}然后在 VFL 语言里面所用到的距离左边位置的距离,可以用leftArglin 来代替,这样的话,改想要修改距离左边的距离,就致用修改字典里面的数值,而不用每个使用到左边距离的地方都意义修改,方便大家,当然这个值可以传 nil

views:就是上面所加入到NSDictionary中的绑定的View,就是需要布局的 view 都需要写入一个字典里面来才可以.
- (void)methodTwo{//VFL(可视化格式语言)_blueV = [[UIView alloc]init];_blueV.backgroundColor = [UIColor redColor];[self.view addSubview:_blueV];_yellowV = [[UIView alloc]init];_yellowV.backgroundColor = [UIColor yellowColor];[self.view addSubview:_yellowV];//注意translatesAutoresizingMaskIntoConstraints 一定要设置为 NOself.blueV.translatesAutoresizingMaskIntoConstraints = NO;self.yellowV.translatesAutoresizingMaskIntoConstraints = NO;//viewsNSDictionary * views = NSDictionaryOfVariableBindings(_blueV,_yellowV);//metresNSDictionary * metres = @{@\"readViewW\":@100,@\"leftArglin\":@50,@\"rightArglin\":@50};//水平方向的约束NSArray * HContraints = [NSLayoutConstraint constraintsWithVisualFormat:@\"H:|-leftArglin-[_blueV(readViewW)]-11-[_yellowV]-rightArglin-|\"options:0metrics:metresviews:views];//垂直方向的约束NSArray * VContraints = [NSLayoutConstraint constraintsWithVisualFormat:@\"V:|-20-[_blueV(50)]-20-[_yellowV(==_blueV)]\"options:0metrics:metresviews:views];//添加约束[self.view addConstraints:HContraints];[self.view addConstraints:VContraints];}

5、举个例子

例子1: H:|-20-[_blueV(50)]-11-[_yellowV(50)]-20-|

分开讲解:

1)H:| -20-水平方向的布局是从屏幕的左侧20开始

2)[_blueV(50)]代表_blueV的宽度是50

3)-11-表示距离下一个控件的距离是11

4)[_yellowV(50)]代表_yellowV的宽度是50

5)-20-|表示距离屏幕右侧为20

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » NSLayoutContraint的使用