布局的两种模式
1,基于父视图参考系的偏移frame 基于父视图比例自动补偿调整。
2,基于容器约束和内容压力求解视图位置 动态求解替代补偿模式
内容压力:负压力(吸引边框)正压力(排斥边框)
*经过alloc init出来的对象默认支持frame方法
*经过storyboard拖出来的默认支持auto layauto(约束)
平衡约束和内容压力的优先级
约束自身的宽和高,,约定宽高比
容器、父视图-----距离父视图的上下左右各是多少,距离中心
同级视图 宽高的关系,对齐
代码建立约束 建立约束宽度
view!.attr1<relation>multi;tier * view2.attr2 + c.
NSLayoutConstraint * c1 = [NSLayoutConstraint constraintWithItem: attribute:(NSLayoutAttribute) relatedBy: toItem: attribute: multiplier: constant: ];
1.strut模式
strut的中文直译有支持的意思,其布局也取自此意。用通俗的翻译来说这个机制就是:对父视图的固定偏移。在学习UIView对象以后,咱们知 道,UIView对象能够有自身的子视图,同时负责维护子视图的位置。而UIView自身的位置,则是经过CGRect类型的结构体变量frame所描 述,描述内容之中便包含基于父视图的固定偏移量。
肯定位置,首先须要肯定参考系(也称坐标系)。只有在肯定参考系以后,才能根据参考系肯定自身的位置。在肯定参考系时有两种状况:
UIWindow对象的参考系
非UIWindow的视图对象的参考系
首先咱们来研究UIWindow对象的参考系,因UIWindow对象显示不须要父视图,因此规定其位置的参考系即是屏幕自己。
参考系的规定以下
左上角顶点为参考系原点
水平向右为x正方向
垂直向下为y正方向
参考系大小以下图所示,不一样机型的参考系不同
参考系大小于屏幕像素点关系
因为历史和当前市场产品的一些缘由,如今所描述的视图参考系的大小并不等于手机屏幕真实的像素数量。以iPhone4为例,其屏幕像素点的个数为 高:960,宽:640。但描述屏幕的参考系大小为480×320。经过简单运算可知,屏幕像素为参考系的2倍,即一个参考系中的点,须要用4个像素去描 绘,全部iPhone的显示效果很是细腻。采用2倍大小的还有iPhone4s、iPhone五、iPhone5s、iPhone6
iPhone6 Plus的参考系和屏幕像素的关系较为特殊。6Plus的参考系大小如图所示为x:414,y:736。同时6Plus的显示芯片采用9个像素描绘一个点,使显示内容更加细腻。这样其显示芯片须要生成一个2208×1242的图像,为参考系大小的3倍。
但6Plus为兼容市面上绝大多数的大屏手机分辨率,本身的屏幕分辨率也设计为1920×1080。为了将显示芯片渲染的2208×1242图像显 示在1920×1080的屏幕上,在显示中,手机自动将原始图像缩小1.15倍(2208÷1.15=1920)。因此,面向6Plus进行开发工做时, 开发人员和设计人员眼中的6Plus分辨率应该为2208×1242,但用户看到的实际大小应该为1920×1080。
strut模式中,经过CGRect结构体变量描述一个基于参考系的矩形区域。其中包含该矩形区域左上角顶点在参考系中的位置和矩形自身的长和高。建立UIWindow对象时,经过UIScreen对象获取当前屏幕的高度和宽带用来建立UIWindow对象。
UIScreen * screen = [UIScreen mainScreen]; CGSize size = screen.bounds.size; CGPoint orgion = CGPointMake(0, 0); CGRect frame; frame.origin = orgion; frame.size = size; UIWindow * window = [[UIWindow alloc]initWithFrame:frame]; [window makeKeyAndVisible]; 肯定UIWindow位置和大小的参考系就是屏幕参考系。也能够说,window对象的位置是基于屏幕。 接下来咱们继续研究非UIWindow的视图对象的参考系。因非UIWindow的视图对象须要加入视图树中才可以被显示,也就是须要做为已经显示在屏幕上的视图的子视图。 可以在屏幕上看到的视图对象必定有一个父视图,这个父视图对象即是子视图的参考系。默认状况下,参考系的原点为父视图的左上角顶点,参考系的边界为父视图的边界。但此默认状况能够经过配置bounds属性调整。 UIView * redView = [[UIView alloc]initWithFrame:CGRectMake(50, 50, 100, 100)]; 表示建立了一个视图,这个视图的左上角顶点,距离父视图左上角顶点偏移了(50,50),自身的大小为100×100。此时没法肯定该视图在屏幕上的位置,因还不知道父视图在屏幕上的位置。全部这里的frame属性仅仅是基于父视图的偏移量。 若是子视图自身大小超出了父视图的边界,也就是参考系边界,那么超出部分是否显示由父视图决定,经过父视图的clipsToBounds属性 // When YES, content and subviews are clipped to the bounds of the view. //Default is NO. @property(nonatomic) BOOL clipsToBounds; bounds属性 上文中说,视图参考系默认状况下是父视图提供的,其原点为父视图的左上角顶点,参考系边界为父视图边界。但也能够经过配置bounds属性的值来调整参考系原点和边界大小。 // default bounds is zero origin, frame size. @property(nonatomic) CGRect bounds; 在配置视图的frame属性时,bounds属性也会自动变换,经过注释能够看出,其origin值为zero,size值为frame中的size值。 bounds的origin主要是改变子视图参考系原点的位置。默认状况下origin为(0,0)表示:父视图左上角顶点是子视图参考系的原点。 但若是经过代码改变其值为(10,10),那么父视图左上角顶点将再也不是子视图参考系的原点,而是(10,10)点,原点向上移动10个点,向左移动10 个点。这是,子视图的frame没有变换,可是父视图参考系发送变换,一样会引发子视图的位置改变。这个属性的使用场景这里暂不展开讲解。在以后章节中, 会进行深刻介绍。 一样,咱们能够经过bounds的size值来改变提供子视图参考系的边界大小。一般开发中不会主动调整此值,以避免带来未知问题,例如按钮不能点击等,由于参考系边界不只和现实相关还与时间传递有关,这里暂不深刻。 2.spring模式 spring模式是位置的一种补偿模式。经过上文中的strut模式能够肯定一个子视图在父视图中的固定偏移量。可是再实际使用时,经常会出现父视 图大小会发生改变的状况。好比App有竖屏模式转为横屏模式,此时若是不从新调整子视图相对于父视图的偏移量,将会出现现实错误。例以下图: 这是便须要根据父视图参考系的变化状况,提供一个动态的补偿机制,spring即是提供补偿机制的模式。 补偿机制是双休的,因此须要父视图的参考系发生变化时告知子视图,同时子视图须要根据变化作出相应的响应。 父视图经过autoresizesSubviews属性值来判断,是否告知子视图,自己的参考系发生变化。 // default is YES. //if set, subviews are adjusted according to their autoresizingMask if self.bounds changes @property(nonatomic) BOOL autoresizesSubviews 子视图经过autoresizingMask属性值作出相应的响应。 // simple resize. default is UIViewAutoresizingNone @property(nonatomic) UIViewAutoresizing autoresizingMask; UIViewAutoresizing为响应状况枚举: UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5 autoresizingMask的默认值为UIViewAutoresizingNone,表示子视图的位置和大小按照当前在父视图参考系中的比例进行调整。调整方式以下图所示: 若是将autoresizingMask的值设置为枚举值中内容,那么该内容表示的尺寸将不作调整,例如UIViewAutoresizingFlexibleWidth表示,子视图自己的宽带将不会随父视图参考系变化二变化,如图所示 spring模式下的调整只能进行按比例缩放和固定,没法根据具体的要求进行补偿,如今基本再也不使用此模式。 3.Auto Layout AutoLayout模式是iOS6 SDK所支持的新机制。使用AutoLayout能够在不久层次结构中表示一个视图与自身、父视图、兄弟视图的关系。这些关系能够包含等式关系和不等式关 系,也可能涉及视图的属性,例如位置、范围。这些特性使AutoLayout可以以一种spring模型没法实现的方式实现精妙的边界条件。举例来讲,你 可能会说“我想让这些等尺寸的视图排成一行,可是和父视图的边界距离不得小于20个点”或者“若是水平空间不足,我想在任何右边按钮受到影响前,让左边按 钮的文本先被裁减”。 代码中默认使用strut和spring模式。但从对spring和AutoLayout的功能描述上来看,两个功能明显冲突,都是对视图的布局进 行调整,spring是根据固定模式进行调整,而AutoLayout是须要根据约束进行求解。全部在同一个视图对象上,只能使用两种模式中的一共。须要 手动关闭strut和spring模式,才能使用AutoLayout模式。 关闭strut和spring的方法是经过视图对象的一个方法,经过设置flag为NO值,关闭strut和spring布局模式。 - (void)setTranslatesAutoresizingMaskIntoConstraints:(BOOL)flag 在AutoLayout模式下,每一个视图对象在屏幕上的位置都是经过约束和内容压力求解出来的。 3.1约束 约束就是视图几何关系的限制条件,主要能够分红三类: 自身约束:宽度约束、高度约束 相对父视图约束:视图四边与父视图四边的距离、视图水平中心与父视图水平中心的距离、视图垂直中心与父视图垂直中心的距离。 兄弟视图间约束:水平间距,垂直间距,边缘对其,中心对其,尺寸匹配 兄弟视图定义:拥有相同父视图的视图对象。 建立约束的方法有三种: 使用生成约束的方法建立约束 使用约束描述字符串生成约束 使用Interface Builder添加约束 首先咱们研究经过方法建立约束 UIView * view1; UIView * view2; NSLayoutAttribute att1; NSLayoutAttribute att2; CGFloat multiplier; CGFloat constant; NSLayoutRelation relation; NSLayoutConstraint * constraint = [NSLayoutConstraint constraintWithItem:view1 attribute:att1 relatedBy:relation toItem:view2 attribute:att2 multiplier:multiplier constant:constant]; NSLayoutAttribute为属性枚举参数: NSLayoutAttributeLeft = 1, NSLayoutAttributeRight, NSLayoutAttributeTop, NSLayoutAttributeBottom, NSLayoutAttributeLeading, NSLayoutAttributeTrailing, NSLayoutAttributeWidth, NSLayoutAttributeHeight, NSLayoutAttributeCenterX, NSLayoutAttributeCenterY, NSLayoutAttributeBaseline, Left,Right,Top,Bottom为视图的四个边框 Leading,Trailing为视图的前边和后边。此处前边和后边是针对阅读顺序而言,对用中文,英文类的语言,左边就是前边,右边就是后边, 而对用阿拉伯文等从右向左阅读的文字,前边就是右边,后边就是左边。一般建议使用先后作约束,避免使用左右,这样能够更好的进行国际化的适配。 Width,Height表示视图自身的宽高属性 CenterX,CenterY依次表示视图自身水平中心和垂直方向的中心 Baseline为显示文字类组件特有的属性,表示文字显示的基线 NSLayoutRelation为关系枚举参数 NSLayoutRelationLessThanOrEqual = -1, NSLayoutRelationEqual = 0, NSLayoutRelationGreaterThanOrEqual = 1, 分别能够设置等于,小于等于,大于等于。这里在求解约束时,不等式较难理解。一般换一个角度去理解这个不等式,好比小于等于意思就是设置最大值,大于等于的意思就是设置最小值。 这段代码演示了建立约束的通用方式,其约束规定的内容为view1.attr1 关系 view2.attr2 * multiplier + constant。 下面咱们依次举3个列子来说解如何建立约束: 建立一个viewA宽度为10个点的约束 建立一个viewA的左边界距离父视图左边界20个点的约束 建立一个viewA的右边界距离viewB的右边界30个点的约束 UIView * fatherView = [[UIView alloc]initWithFrame:CGRectZero]; fatherView.translatesAutoresizingMaskIntoConstraints = NO; UIView * viewA = [[UIView alloc]initWithFrame:CGRectZero]; viewA.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewA]; UIView * viewB = [[UIView alloc]initWithFrame:CGRectZero]; viewB.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewB]; //建立一个viewA宽度为10个点的约束 NSLayoutConstraint * constraint_viewA_width = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:10]; //装载约束到父视图上 [fatherView addConstraint:constraint_viewA_width]; 建立一个viewA的左边界距离父视图左边界20个点的约束 NSLayoutConstraint * constraint_superView_20_viewA = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:fatherView attribute:NSLayoutAttributeLeading multiplier:0 constant:20]; //装载约束到父视图上 [fatherView addConstraint:constraint_superView_20_viewA]; //建立一个viewA的右边界距离viewB的右边界30个点的约束 NSLayoutConstraint * constraint_viewA_30_viewB = [NSLayoutConstraint constraintWithItem:viewA attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:viewB attribute:NSLayoutAttributeLeading multiplier:0 constant:30]; //装载约束到父视图上 [fatherView addConstraint:constraint_viewA_30_viewB]; >代码中用NSLayoutAttributeLeading表示左边,NSLayoutAttributeTrailing表示右边 >视图对象的约束必定要装载到其父视图身上,视图对象的自我约束力不够,须要父视图管理才能够。 接下来咱们继续研究经过约束描述字符串生成约束用字符串主要描述一下两点 * 边界之间的间距 * 自己宽高 设计一下3个关键符号 * `| `表示父视图边界,根据字符串语义断定哪一个边界 * `[] `表示视图对象,例如`[aView] `表示aView视图对象,经过一个`@{@"aView":aView} `字典进行绑定 * `-x- `表示距离,x为数组或字符,例如`-20- `或者`-tempX- `,经过一个`@{@"tempX":@20} `字典对字符串中的tempX进行数值绑定。 * `H: `表示水平方向 * `V: `表示垂直方向 举例: * `H:[aView(100)] `表示aView的宽带为100 * `H:|-20-[aView] `表示aView的左边界距离父视图的左边界为20个点。 * `V:[aView]-10-| `表示aView的下边界距离父视图的下边界为10个点。 * `V:[aView(30)] `表示aView的高度为30 采用字符串描述约束的核心优点是能够同时描述多个视图对象 * `H:|-20-[aView]-40-[bView(==aView)]-20-| `表示,aView和bView等宽,其间距40,分别距离父视图两边20。 * `V:|-20-[aView(40)][bView(50)] `表示,aView高度40,距离父视图上边界20,bView高度50紧贴aView下边。 经过NSLayoutConstraint的constraintsWithVisualFormat方法将描述约束的字符串生成约束对象。 NSString * constraint_string = @"|-x-[viewA(20)]"; NSDictionary merticsDic = @{@"x":@10}; NSDictionary viewsDic = @{@"viewA":viewA}; NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:constraint_string options:NSLayoutFormatDirectionLeadingToTrailing metrics:merticsDic views:viewsDic]; [fatherView addConstraints:constraints]; >方法中options参数是枚举值,主要描述文字的阅读方式是从左到右,仍是从右到左,一般选择NSLayoutFormatDirectionLeadingToTrailing表示根据语言环境决定从前到后。 > NSLayoutFormatDirectionLeadingToTrailing, NSLayoutFormatDirectionLeftToRight, NSLayoutFormatDirectionRightToLeft, >方法中的metrics是一个字典,字典中的key为字符串中描述数值的字符,value为该字符对应的真实值。 >方法中的views是一个字典,字典中的key为字符串中描述视图对象的字符,value为该字符对应的真实对象。为了方便建立此类型字典UIKit中提供一个宏方便建立字典`NSDictionaryOfVariableBindings(<#...#>) `。 > NSDictionary * dic = NSDictionaryOfVariableBindings(aView); 至关于@{@"aView":aView}字典 >因一个字符串中能够描述多个约束,因此返回一个数组,数组中为此字符串描述的全部约束对象。 >经过调用父视图的addConstraints方法,一次装载多个约束。 下面咱们重复上节的3个列子来演示如何用描述字符串建立约束 * 建立一个viewA宽度为10个点的约束 * 建立一个viewA的左边界距离父视图左边界20个点的约束 * 建立一个viewA的右边界距离viewB的右边界30个点的约束 UIView * fatherView = [[UIView alloc]initWithFrame:CGRectZero]; fatherView.translatesAutoresizingMaskIntoConstraints = NO; UIView * viewA = [[UIView alloc]initWithFrame:CGRectZero]; viewA.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewA]; UIView * viewB = [[UIView alloc]initWithFrame:CGRectZero]; viewB.translatesAutoresizingMaskIntoConstraints = NO; [fatherView addSubview:viewB]; //建立绑定字典 NSDictionary * views = NSDictionaryOfVariableBindings(fatherView,viewA,viewB); //建立一个viewA宽度为10个点的约束描述字符串 NSString * constraintString1 = @"H:[viewA(10)]"; //经过字符串生成约束 NSArray * constraints1 = [NSLayoutConstraint constraintsWithVisualFormat:constraintString1 options:0 metrics:nil views:views]; //装载约束到父视图上 [fatherView addConstraints:constraints1]; //建立一个viewA的左边界距离父视图左边界20个点的约束 NSString * constraintString2 = @"H:|-20-[viewA]"; //经过字符串生成约束 NSArray * constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:constraintString2 options:0 metrics:nil views:views]; //装载约束到父视图上 [fatherView addConstraints:constraints2]; //建立一个viewA的右边界距离viewB的右边界30个点的约束 NSString * constraintString3 = @"H:[viewA]-30-|"; //经过字符串生成约束 NSArray * constraints3 = [NSLayoutConstraint constraintsWithVisualFormat:constraintString3 options:0 metrics:nil views:views]; //装载约束到父视图上 [fatherView addConstraints:constraints3]; >经过对比能够看出,经过描述字符串生成约束的方法更加简单直观。固然,更简单的方式是经过IB(Interface Builder)添加约束,关于IB的使用,请参加视频教程。 **3.2内容压力** --- 内容压力能够影响装载内容的对象外形尺寸。这里用UIImageView对象举例子,其余装载内容的视图对象用法一致。 在AutoLayout模式下,内容能够对组件边界产生两种压力 * 正压力:迫使组件改变自身的大小来显示完整的内容。 * 负压力:迫使组件维持当前的大小来显示完整内容。 这样描述比较抽象,举个例子: 如今有一张200×200的图片须要用一个UIImageView视图对象来显示。 **正压力** 若是我这是UIImageView视图对象的宽高都为100,那么内容会产生正压力,迫使视图的宽高都变为200,这样才能完整显示图片内容。 **负压力** 若是我这是UIImageView视图对象的宽高都为300,那么内容会产生负压力(吸引力),迫使视图的宽高都变为200,这样才能完整显示图片内容,而不留空白。 内容产生的压力可否是视图尺寸发送改变取决于如下两个因素: * 压力的大小 * 约束力的大小 >这里的大小在代码中用优先级来描述,优先级高的表明力量大,在求解时起主导做用。每个约束均可以配置其优先级,同时也能够配置内容压力的优先级。 压力的优先级经过两个方法分别进行配置 //设置正压力的大小 [viewA setContentCompressionResistancePriority:<#(UILayoutPriority)#> forAxis:<#(UILayoutConstraintAxis)#>] //设置负压力的大小 [viewA setContentHuggingPriority:<#(UILayoutPriority)#> forAxis:<#(UILayoutConstraintAxis)#>] >设置压力时,须要经过Axis方法参数制定水平仍是数值方向,UILayoutConstraintAxis是枚举类型,其枚举值为UILayoutConstraintAxisHorizontal和UILayoutConstraintAxisVertical。 >压力优先级为CGFloat类型,范围是1-1000。其中系统给定了几个默认值: > UILayoutPriorityRequired=1000 UILayoutPriorityDefaultHigh=750 UILayoutPriorityDefaultLow=250 UILayoutPriorityFittingSizeLevel=50 约束力的优先级经过约束的`priority `配置,在约束装载到视图以前能够任意更改优先级,一旦,约束装载到了视图上,约束的优先级便不可再更改,若是须要更该,须要删除以前的约束,从新建立。 @property UILayoutPriority priority; 其类型与压力优先级一致。 下面咱们经过代码演示一下内容压力和约束力直接的较量。仍是经过本节一开始的例子,一个图片大小为200×200。一个UIImageView的宽高约束为100×100。此时,UIImageView对象的最终大小由内容压力和约束较量以后决定。 若是内容压力大于约束力,最终UIImageView的大小为200×200 //获取一个图片对象,该图片大小为200×200 UIImage * image = [UIImage imageNamed:@"testImage.jpg"]; //建立一个UIImageView显示该图片 UIImageView * imageView = [[UIImageView alloc]initWithImage:image]; imageView.translatesAutoresizingMaskIntoConstraints = NO; //设置其内容在水平和垂直方向的压力为501 [imageView setContentCompressionResistancePriority:501 forAxis:UILayoutConstraintAxisHorizontal]; [imageView setContentCompressionResistancePriority:501 forAxis:UILayoutConstraintAxisVertical]; //将视图对象贴在视图控制器的根视图上 [self.view addSubview:imageView]; //建立距离父视图左边间接约束 NSArray * c1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c1]; //建立距离父视图上边间接约束 NSArray * c2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c2]; //建立视图宽带和高度的约束,并设置其约束力为500小于501 NSLayoutConstraint * c3 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c3.priority = 500; [self.view addConstraint:c3]; NSLayoutConstraint * c4 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c4.priority = 500; [self.view addConstraint:c4]; 运行效果以下图所示  若是内容压力小于约束力 self.view.backgroundColor = [UIColor whiteColor]; //获取一个图片对象,该图片大小为200*200 UIImage * image = [UIImage imageNamed:@"testImage.jpg"]; //建立一个UIImageView显示该图片 UIImageView * imageView = [[UIImageView alloc]initWithImage:image]; imageView.translatesAutoresizingMaskIntoConstraints = NO; //设置其内容在水平和垂直方向的压力为501 [imageView setContentCompressionResistancePriority:499 forAxis:UILayoutConstraintAxisHorizontal]; [imageView setContentCompressionResistancePriority:499 forAxis:UILayoutConstraintAxisVertical]; [self.view addSubview:imageView]; //建立距离父视图左边间接约束 NSArray * c1 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c1]; //建立距离父视图上边间接约束 NSArray * c2 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[imageView]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(imageView)]; [self.view addConstraints:c2]; //建立视图宽带和高度的约束,并设置其约束力为500小于501 NSLayoutConstraint * c3 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c3.priority = 500; [self.view addConstraint:c3]; NSLayoutConstraint * c4 = [NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:100]; c4.priority = 500; [self.view addConstraint:c4]; ``` 运行效果以下图所示 内容驱动布局是AutoLayout的核心优点,经过这样的机制,能够不写代码,便实现不一样内容的显示模式下,自动平衡视图组件的尺寸。