autolayout 比例约束的约束冲突该怎么分析

AutoLayout之约束(2) - 简书
AutoLayout之约束(2)
约束用firstItem和secondItem属性引用它所影响的视图。这些属性是只读的,而且只能在约束创建期间设置。这两个属性的类型为id类型。
约束,层次结构和边界系统
当约束引用两个视图时,这两个视图一定要属于同一个视图层次结构。对于引用两个视图的约束,只有两种合法的情况:要么一个视图是另一个视图的父视图(即firstItem是secondItem的祖先,或者反过来),要么两个视图必须是某种类型的兄弟。如果视图让约束引用其他情况的视图,将会崩溃的一塌糊涂。
使用约束的时候,经常会出现这些检查,NSView提供了ancestorSharedWithView:方法,但是UIView没有提供。
要让约束进入Auto Layout系统,需要将约束添加到视图中。举例如下:
[myView addConstraint:aConstraintInstance];
因为可视化个事系统返回约束的数组,而不是返回单个约束,所以NSLayoutConstraint类还提供了一种同步添加约束集合的方式。
[myView addConstraints:myArrayOfConstraints];
约束在他们的firstItem和secondItem属性中的最近公共祖先中总有一个天然归宿,
view1和view3之间的约束,应该添加到作为父视图的view3中。
同样,view2和view3之间的约束也属于view3.虽然view3不是view2的父视图,但view3是view2的祖先。
对于view1和view2来说,view3是他们的最近的公共祖先。尽管没有提到是作为第一项还是第二项,但是应该将view1和view2之间的约束添加到view3中。
IB遵循这一规则,我们也应该遵循这一规则,如果要了解每个约束位于IB层次结构中的什么位置,可以在添加到第一项和第二项的最近的公共祖先中的故事版大纲内找到。
约束通常安装在该约束所引用视图的最近的公共祖先中。约束有必要安装在引用的每个视图的公共祖先中。约束中的数字相对于所安装视图的坐标系有意义。视图被视为自身的祖先。
事实上,每个约束自身可以而且应该安装到一个自然且正确的目标视图中。约束在两个视图之间寻找最近的公共祖先,并且将并且将自身,添加到该视图上。如果是一元约束,则安装到第一个视图上。
使用这个类别,可以将针对约束本身调用的install(remove)方法。你需要的关于安装位置的信息已经存在于每个(合法定义)约束中。此外,如果你的约束统一安装在一致的目标中,则删除约束也会很轻松。
autoLayout还提供了一种删除约束的笨办法,从层次结构中删除视图时,自动删除约束。[view removeFromSuperview];然后,引用该视图的约束都会从Auto Layout中自动删除。例如,假设有一个约束,他描述了view1 和 view2之间的关系。view3拥有该约束,因为它是view1 和view2的最近公共祖先。当将view2从其父视图上移除的时候,autoLayout会自动删除view3中的约束。这种删除是系统自动为你删除的,不需要显示的请求。
任何时候,都可以在视图中添加和删除约束。两个内置方法removeConstraint:和removeConstraints:可用来删除给定视图中的一个约束或者一个约束数组。因为这些发放注定是针对目标指针的。因此当视图删除约束时,他们可能不会如你所愿。
例如,假设你构建了一个中心匹配约束,并将该约束添加到了你的视图中。那么你不能用同样的约束去构建该约束的另一个版本。并预期调用removeConstraint方法删除该约束。虽然这两个约束是等价的,但他们不是同一个约束。
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:textField
attributeLNSLayoutAttributeCenterX releatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
[self.view removeConstraint:[NSLayoutConstraint constraintWithItem:textField
attributeLNSLayoutAttributeCenterX releatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
调用这两个方法后,最终得到的结果:self.view实例中仍然包含原来的约束,试图删除第二个约束的请求被忽略了。未能成功删除该视图不支持的约束。
要解决这个问题,有两个办法。第一个办法是在第一次添加约束时候,将他存储在一个局部的变量中,以保存该约束。代码如下:
NSLayoutConstraint *myConstraint =[ NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRElationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
[self.view addConstraint:myConstraint];
[self.view removeConstraint:myConstraint];
要删除一个等价的约束,可以使用上面这样的办法,也可以使用这样的办法。将两个约束进行比较,并删除在数学上与你传递的约束相匹配的约束。第二个办法是用类类别给约束做标记,以便将来找到并删除该约束。删除约束是autolayout 中的一个重要的功能。每当刷新布局时(在设备旋转时最长发生这种情况),都需要删除无效的约束,并用新的约束规则替他们。
知道自己的约束是静态的(在视图的整个生命周期都有效)还是动态的(根据需要更新)可帮助你决定需要何种方法。如果你觉得以后可能需要删除一个约束,可以通过局部变量保存该约束,以便以后从视图中删除;也可以采用以后能搜索该约束的变通方法。
所有约束都使用下列形式的固定结构以及一个关联的优先级。
视图1.属性 R 视图2.属性 * 乘数 + 常数;
上述公式中的每个元素通过约束的对象属性提供。即priority,firstItem,firstAttribute,relation,secondItem,multiplier和constant。使用这些属性可以很方便的将两个约束进行比较。视图将约束最为对象来存储和删除。如果两个约束存储在内存中的不同位置,那么即使这两个约束描述了相同的条件,系统也会认为是两个不同的约束。要使代码不存储在局部变量中,直接添加和删除约束,可以使用比较功能来实现。
下面代码中创建了一个NSLayoutConstraint类别,用来比较两个约束直接的属性,并判断他们是否匹配。isEqualToLayoutConstraint:方法用来判断是否等价,而不考虑优先级。不管开发人员当前指定的优先级如何,两个描述相同条件的约束,在本质上都是等价的。
- (BOOL) isEqualToLayoutConstraint : (NSLayoutConstraint *) constraint{
if (self.firstItem != constriant.firstItem) return NO;
if (self.secondItem != constriant.secondItem) return NO;
if (self.firstAttribute != constriant.firstAttribute) return NO;
if (self.secontAttribute != constriant.secontAttribute) return NO;
if (self.relation != constriant.relation) return NO;
if (self.multiplier != constriant.multiplier) return NO;
if (self.constant != constriant.constant) return NO;
return YES:
安装了约束后,可以对该约束做两件事,可以删除该约束(也许是用一个新规则替换它),也可以修改约束的常数(通常是为视图添加动画效果)。Auto Layout经常使用这两个任务来创建响应用户交互请求的生动界面。
尽管可以创建指向特定用户约束的实例变量和输出口,但是具有高度交互能力的GUI可以创建大量即使添加,修改和删除的约束。轻量级和生命周期较短的约束由于存在时间不长,因此可能不值得直接指向他们。
布局约束法则
下面是一些布局约束的基本法则,应答牢记:1.布局约束是有优先级的 优先级的范围在1到1000之间。优先级高的约束总是比优先级低的约束先得到满足。可以指定的最高优先级是“必须的”优先级(值为1000)。它也是默认优先级。在布局期间,系统浏览你添加的所有约束,并试图全部满足他们。在决定哪个约束的影响较小时,需要用到优先级。当两个约束有冲突的时候,优先级为99的约束会让步优先级为100的约束。2.布局约束没有任何超越优先级的天然“顺序”
所有具有相同优先级的约束都被同时考虑。如果需要优先处理某个约束,就要赋予该约束更高的优先级。3.布局约束是关系,没有方向。不必通过解出右端来计算左端。4.布局约束可以取近似值 可选的约束试图优化他们的结果。假如有这样的约束 view2的顶边应该与view1的底边位于相同的位置。那么约束系统会尽量使这两个视图之间的距离最小,从而将他们挤压到一起。如果有其他防止这两个视图相互接触的约束,那么系统会把他们放的尽可能靠近,最小化这两个视图之间的绝对距离。5.布局约束可以循环
只要所有条件都满足,哪个元素引用哪个元素无关紧要。不要忌讳交叉引用。在这种声明式的系统中,可以进行循环引用,不会遇到无限循环的问题。6.布局约束可以冗余 如果约束不户型冲突,则可以放心地安装多个实现统一布局的约束。7.布局约束可以引用兄弟视图 只要两个视图有共同的视图祖先,既可以将一个视图的子视图中心点与另一个完全不同的视图的中心点对齐。例如,可以创建一个复杂的文本输入视图,并将其最右边的属性与它下方的嵌入式图像视图的右边属性对齐。也可以两个视图一起移动,但是哪一个视图都不是另一个视图的父视图。8.Auto Layout对变形的处理可能不是很好 将autoLayout与变形混用时,要特别小心,尤其是与包括旋转的变形混用的时候。
Auto Layout仅支持保护矩形的变形 在带有不保护矩形的边界变形图的视图上,auto layout不支持非0得对齐insert.9.布局约束不应该在不同的边界系统之间交叉使用。不要交叉进出滚动视图,集合视图和标示图来进行对齐。如果有某种自带边界系统的内容视图。不要跳出另一个视图所在的完全不同的边界系统中。这么做也许不会与你的应用相冲突,但是最好不要这样做,而且auto layout对它的支持性也不是很好。 auto Layout 仅支持保护矩形的交叉边界变形。auto
Layout 不支持交叉使用旋转边界变形与边缘布局约束,如右边,左边,顶部,底部的约束。auto Layout 不支持交叉使用旋转边界变形与尺寸布局约束,如宽度和高度约束。10.布局约束会在运行时失败
如果你的约束不能被解析并且与其他约束有冲突。那么系统会在运行时,放弃那个约束,以便将视图呈现出来。不过这样呈现的布局通常比较难看,很难反应你的意图。 Auto Layout会将所有关于错误的描述发送给Xcode控制台。这些报告可以用来修复约束,使个约束之间彼此协调。11.格式不正确的布局约束会中断应用程序的执行
尽管我们还没有详细的介绍可视化个事。 但是仍然要注意一些可能通过未处理异常导致应用程序崩溃的约束调用。12.约束至少引用一个视图。13.小心无效的属相结对
将一个视图的左边与另一个视图的高度相配是无效的。无效的属性结对会在运行时抛出异常。特别要指出的是:不要将尺寸属性与边缘属性混合使用。14.合理使用Auto Layout.Autolayout学习笔记 - 简书
Autolayout学习笔记
一、Autolayout笔记
1.PPT介绍页面布局的三个时期
2.Autosizing简单使用
1如何固定控件和四周的距离
》讲解如何开启Autosizing (去掉Use Auto Layout)
》Autosizing主要学习六根线
1.周围四根线
a. 用途:用来控制当前控件和父控件的距离的
b. 如果勾选左边线条,代表当前控件与父控件的左边的距离固定,其他依次类推
c. 举例:四个红色方块在控制器view内部,要求无论控制器view如何变化,四个红色方块永远都在控制器view的的四个角上
2.中间的两根:
a. 如果勾选了中间水平方向这条线,则子控件宽度,随父控件宽度的变化而变化.
b. 如果勾选了中间垂直方向这条线,则子控件高度,随父控件高度的变化而变化.
c. 要求:红色控件在蓝色控件内部,(蓝为父,红为子), 红色控件与蓝色控件上下左右的距离不变, 红色控件随着蓝色控件的宽度的变化而变化,点击按钮让蓝色控件的宽高变大
2.代码中使用Autosizing
代码中使用子控件的autoresizingMask属性,来设置子控件与父控件之间的关系的.
需求:搞两个控件,一个蓝色一个红色,形成父子关系,蓝色是父控件,红色是子控件.
让红色控件永远在蓝色的底部,并且红色的宽度必须随着蓝色的变化而变化
》设置autoreizingMask属性距离顶部可拉伸、宽度可拉伸
》"切记":代码中设置某个方向可拉伸代表另一个方向固定和故事板中正好相反
3.autoreizingMask缺陷
》拖入两个view并设置view宽度为130, 要求两个View距离左右和顶部永远是20
》设置A控件距离左边顶部固定, 设置B控件距离右边顶部固定, 运行查看效果
》设置A,B控件内部是可拉伸的, 运行查看效果
》无论如何Autosizing无法满足需求,因为Autosizing是相对父控件计算的,不能单独设置两个控件之间的条件
3.Autolayout简单实用
Autolayout基本概念 (让控件居中并距离上下左右50)
》讲解如何打开Autolayout(勾选Use Auto Layout)
为了我们能够使用autolayout,必须勾选, 为了更清楚的认识autolayout, sizeclass 先不要勾选.
&Autolayout的原理
&没有使用auturesizing/autolayout时是设置frame , 设置frame其实就是告诉系统控件的X/Y/宽/高.
&以前可以通过frame直接设置控件的X/Y/宽/高.
&以前可以通过auturesizing间接设置控件的X/Y/宽/高.
&so使用autolayout时也是间接设置控件的X/Y/宽/高即可
&系统会根据约束自动调整
》讲解故事版底部几个按钮作用
1.让子控件永远居中, 宽高永远100
1.0 拖入一个控件设置尺寸为100,100 ,位置随便放置
1.1添加距离在父控件中心地约束
1.2 红色箭头:表示缺少约束或约束冲突
1.3.添加宽高的约束
1.4 黄色箭头:黄色箭头代表当前控件的X或Y或宽或高和autulayout约束的不一致
1.5 如何修复黄色箭头,两种方式
1.6 演示红色箭头的另一个原因,约束冲突,添加一个宽度为200的约束
1.7 演示如何修复红色箭头
2.举例:让控件居中,并且距离上下左右都是50
2.1 拖入一个view,背景设置为蓝色,调整尺寸
2.2 添加距离父控件上下左右距离的约束
2.3 如何删除约束
4. Autolayout其他用法
控制器的view内部有红蓝两个view,红色的view与蓝色的view时兄弟关系.
要求:红色的view距离控制器的view左边20固定,底部20固定,高度100固定
蓝色view与控制器view右边20底部20,宽度和高度与红色view相同,
蓝色view与红色的view之间的间隙为20
"注意":当有多个view的时候,建议一个一个搞,当多同时搞的话就容易搞混
方法1:多控件宽高相等(练习1)
》设置A控件左下固定(相当于设置X和Y)
》B控件右下固定 (相当于设置X和Y)
》设置AB控件中间固定
》设置两个控件宽度相等 (统自动推算, 相当于设置宽度)
》设置A控件高度
》设置两个控件高度相等(相当设置B高度)
方法2:多控件顶部底部对齐 (练习1)
》设置A控件左下固定、B控件右下固定
》设置AB控件中间固定
》设置两个控件宽度相等
》设置A控件高度
》设置B和A顶部底部对齐
控制器的view中有红色View和蓝色View
蓝色view距离控制器的view顶部以及左右都是20,高度为100
红色的view与控制器view的右边的间距也为20
红色view在蓝色view下方,红色view与蓝色view之间的间隔为20
红色view与蓝色view的高度相同,宽度是蓝色view的一半
firstItem(redView.width) = secondItem(blueView.width) * 0.5 +
Constant(0)
》设置A控件距离上左右固定 (相当于设置X/Y/宽)
》设置A控件高度固定
》设置B控件宽高等于A控件
》设置B控件距离A控件底部固定
》设置B控件和A控件右对齐
》讲解公式
view1.attr1 &relation& view2.attr2 * multiplier + constant
》修改乘积为0.5运行查看效果
》利用修改水平居中约束实现
第三节: Autolayout使用技巧
使用一张图片作为主页界面,无论是在4s 还是5/5s上都可以正常显示
创建项目去掉sizeclasses,拖入图片,storyboard中拖入imageView,设置imageView的图片 ,完成后如图所示:
1.UIImageView如果有图片就可以不添加它宽高约束,系统把image图片的宽高作为UIImageView的宽高
2.UILabel如果有内容也可以不添加宽高约束,系统会根据UILabel的内容来确定它的宽高
3.系统中还有一些控件默认就宽高如 UISwitch,UIButton 系统自带几种类型 等,也不用设置宽高约束
使用一张图片作为主页界面,主界面上有按钮的位置添加一个按钮控件,无论是在4s 还是5/5s上都可以正常显示,如图
第一节:(理解)
Autolayout代码实现
1.PPT讲解添加约束的规则
1)对于两个同层级view之间的约束关系,添加到它们的父view上
2)对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上
3)对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上
4)只与自己本身有关系,添加到自己上(如固定的宽或高)
2.代码实现Autolayout概念(PPT讲解)
》切记:要先禁止autoresizing功能,设置view的下面属性为NO
》切记:添加约束之前,一定要保证相关控件都已经在各自的父控件上
3.Autolayout约束的代码创建[了解]
o 一个NSLayoutConstraint对象就代表一个约束
o 创建约束对象的常用方法
+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
o view1 :要约束的控件
o attr1 :约束的类型(做怎样的约束)
o relation :与参照控件之间的关系
o view2 :参照的控件
o attr2 :约束的类型(做怎样的约束)
o multiplier :乘数
核心公式: view1.attr1 &relation& view2.attr2 * multiplier
4.编程实现(添加控件,要求款到100并且居中)
》对照公式讲解NSLayoutConstraint对象每个参数的含义
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1,
NSLayoutAttributeRight,
NSLayoutAttributeTop,
NSLayoutAttributeBottom,
NSLayoutAttributeLeading,
NSLayoutAttributeTrailing,
NSLayoutAttributeWidth,
NSLayoutAttributeHeight,
NSLayoutAttributeCenterX,
NSLayoutAttributeCenterY,
NSLayoutAttributeBaseline,
//文本底标线
NSLayoutAttributeNotAnAttribute = 0
//没有属性
其中leading与left trailing与right 在正常情况下是等价的 但是当一些布局是从右至左时(比如阿拉伯文) 则会对调,换句话说就是只用left和right就好了
typedef NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1,
//小于等于
NSLayoutRelationEqual = 0,
NSLayoutRelationGreaterThanOrEqual = 1,
//大于等于
》创建4个约束宽高、CenterX 、CenterY添加后运行查看效果
控制器的view中有红色View和蓝色View
蓝色view距离控制器的view顶部以及左右都是20,高度为100
红色的view与控制器view的右边的间距也为20
红色view在蓝色view下方,红色view与蓝色view之间的间隔为20
红色view与蓝色view的高度相同,宽度是蓝色view的一半
使用纯代码
》添加控件并禁止Autoresizing
》创建蓝色控件约束(高度、距离左边、顶部、右边)
》创建红色控件约束(右边等于蓝色、高度等于蓝色、顶部对齐蓝色底部、宽度等于蓝色一半)
第二节: VFL(了解):
2.控制器的view中有红色View和蓝色View
蓝色view距离控制器的view顶部以及左右都是20,高度为100
红色的view与控制器view的右边的间距也为20
红色view在蓝色view下方,红色view与蓝色view之间的间隔为20
红色view与蓝色view的高度相同,宽度是蓝色view的一半
使用VLF语言
2.Masonry[理解]
Masonry,“一个轻量级的布局框架,采用更"优雅"的语法封装自动布局”,不需要使用XIB和Storyboard, 并具有高可读性 而且同时支持 iOS 和 Max OS X
Masonry尤其适合习惯纯代码开发的开发者 ,在iPhone6发布后引发的适配潮中 Masonry一定可以助你一臂之力
1.创建项目
2.导入框架(把框架代码拷贝过来)
3.根据示例程序来写[介绍pch文件]
Masonry常用方法
在控制器上添加一个控件,在控制器view的中心,宽高均为200
三个添加约束方法区别
mas_makeConstraints 只负责新增约束 Autolayout不能同时存在两条针对于同一对象的约束 否则会报错
mas_updateConstraints 针对上面的情况 会更新在block中出现的约束 不会导致出现两个相同约束的情况
mas_remakeConstraints 则会清除之前的所有约束 仅保留最新的约束
三种函数善加利用 就可以应对各种情况了
两个赋值方法区别(equalTo 和 mas_equalTo)
#define equalTo(...)
mas_equalTo(__VA_ARGS__)
#define mas_equalTo(...)
equalTo(MASBoxValue((__VA_ARGS__)))
mas_equalTo对其参数进行了一个自动装箱操作, 除了支持NSNumber数值类型之外还支持CGPoint CGSize UIEdgeInsets
//define this constant if you want to use Masonry without the 'mas_' prefix
//你如果希望不加mas_使用Masonry就定义这个宏
#define MAS_SHORTHAND
//define this constant if you want to enable auto-boxing for default syntax
//如果你希望启用自动加包解包(基本数据类转对象类型称为加包,对象类转对象类型称为解包,自动加解包为auto-boxing)就定义这个宏
#define MAS_SHORTHAND_GLOBALS
Masonry练习
在控制器上添加一个控件,距离控制器View上下左右各20
方式一逐个设置 make.top.equalTo
方式二连续设置 make.top.left
make.bottom.and.right.equalTo
注意:这里的and和with 其实这两个函数什么事情都没做
and和with方法直接
方式三一次性设置 make.edges.equalTo
控制器的view中有红色View和蓝色View
蓝色view距离控制器的view顶部以及左右都是20,高度为100
红色的view与控制器view的右边的间距也为20
红色view在蓝色view下方,红色view与蓝色view之间的间隔为20
红色view与蓝色view的高度相同,宽度是蓝色view的一半
1.AutoLayout中使用动画
1.约束可以拖线到控制器
2.可以修改约束
3.执行动画的时候,调用layoutIfNeeded
2.sizeclass
介绍sizeclass的作用
使用sizeclass来实现QQ登录界面
1.创建一个通用的项目
2.使用autolayout来约束界面
1.sizeclass 设置为Any & Any
2.QQ头像水平居中,紧挨导航栏
3.文本框宽度200,水平居中,顶部据头像的距离为20
4.文本框宽度200,水平居中,距离上面的文本框为20
5.预览在所有设备上都是正常的
3.images.xcassets在Xcode6中的变化
4.sizeclass安装
选中控件,在该控件的属性面板的最下面
新浪微博使用autolayout来做
1.创建项目拖入资源
2.创建文件
3.拷贝数据模型文件
4.修改storyboard中的控制器为UITableViewController
5.删除原来viewController,创建一个CZMicroBlogController继承自UITableViewController
6.设置storyboard中的控制器为custom class 为CZMicroBlogController
7.在控制提供microBlogs的属性,然后懒加载它
8.storyboard中使用autolayout布局cell
此时布局icon,name,vip和text
9.创建CZMicroBlogCell类继承UITableViewCell
10.设置storyboard中的cell的custom class为CZMicroBlogCell
11.在CZMicroBlogCell.m文件中,定义类扩展,然后stroyboard中cell的子控件拖线到类扩展中
12.在CZMicroBlogCell.h文件中,提供一个数据模型属性,重写该属性的setter方法,给子控件赋值
13.在控制器中实现数据源方法
14.在viewDidLoad方法中设置
行高动态计算
self.tableView.rowHeight = UITableViewAutomaticD
和估算行高
self.tableView.estimatedRowHeight = 44;
15.处理最下面的图片
1.在storyboard中的cell中拖入一个UIImageView
2.添加相关约束
3.拖线到自定义cell中
4.在setMicroBlog:中,判断有存在图片,就给设置图片,否则隐藏,运行没有显示的图片的依然占据位置
5.把pictureView上的控制器行高的约束拖过来,如果没有图片就把行高约束设置为0,否则设置100
二、学习链接
Autolayout基础知识1).2).
自学:在Autolayout中如果是对ScorllerView和TableView是需要特殊处理而且在ios8中相比ios7 , TableView还需要更进一步的处理江哥提示:TableView中使用Autolayout1).2).iOS AutoLayout自动布局中级开发教程(5)-修改约束的值,延迟加载
如何修改autolayout 约束的值?
目前我已知的方法有5种
1.修改frame(有时候可能会不起作用,但可以做动画)
2.修改约束的float值
3.使用VisualFormat&语言
4.使用&constraintWithItem,按倍率改变&&&如&&2x+1=Y&
5.移除约束(remove&at&runtime),添加新的约束
前面的文章已经讲到如何使用storyboard 创建约束了,但是在实际的开发中我们经常需要适配不同的屏幕尺寸和版本,这时我们就 需要用代码对 我们的布局进行适当的调整了,
先来介绍第2种方法:
直接修改 约束的值 ,这是最直接最简单,官方推荐的方法!比移除 约束再添加约束省事不少!
首先咱们来拖拽一个 view到 viewController上,设置好 上左宽高的值,确定 view的位置:
效果和约束值如下:
可以看出,约束是: 距离左边 10,上边 61,宽高未117,111
我们对图中的ViewController绑定类之后,拖拽 几个约束到 绑定的ViewController类的 延展中去:
如何拖拽?:
我们试着拖拽左边约束 和高度约束到 viewcontroller.m的延展中去
拖拽过程中会产生一条线,松手后需要你给这 outlet填写一个名词,点击connect或者回车 ,代码中就有啦!
原拖拽成功的最终在代码中的效果是:
下面我们来修改 ,这个view的 top上边界的,和 view的高度,使其都增加100:
ViewController.m
Created by http://blog.csdn.net/yangbingbinga 15/1/21.
Copyright (c) 2015年 http://blog.csdn.net/yangbingbinga All rights reserved.
#import ViewController.h
@interface ViewController ()
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.top.constant+=100;
self.height.constant+=100;
当我们注释 这段 代码的时候,运行的效果是这个样子的:
可以看到,这个 view的宽高我们设置的是一样的:
当我们把注释打开时:
ViewController.m
Created by http://blog.csdn.net/yangbingbinga 15/1/21.
Copyright (c) 2015年 http://blog.csdn.net/yangbingbinga All rights reserved.
#import ViewController.h
@interface ViewController ()
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.top.constant+=100;
self.height.constant+=100;
运行效果如下:
可以看到top的值 ,,和之前比 增加了100,高度也增加了100!
可以说明的是,每一个
NSLayoutConstraint的对象,都有 constant 值,我们 拖拽到代码中可以直接改变其值,也不会产生任何警告和冲突!
但是,这还没完,你在开发时可能会遇到,在 viewDidLoad中修改 过
constant值,或者修改其他约束的值,却没有产生任何效果:
:你在storyboard设置的约束是这样处理的
你在 viewDidLoad中修改的约束的代码块运行了,但是 运行完之后 又被 storyboard自己的配置给覆盖了,所以 你看到的还是你之前设置的约束!
解决办法: 让修改
constant值或者约束的语句延迟执行即可!即使是 0.1秒,也能让 在storyboard初始完成之后你再修改相应的约束,这样就不会被覆盖掉了!
具体方法:见代码
ViewController.m
Created by http://blog.csdn.net/yangbingbinga 15/1/21.
Copyright (c) 2015年 http://blog.csdn.net/yangbingbinga All rights reserved.
#import ViewController.h
@interface ViewController ()
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
[self performSelector:@selector(modifyConstant) withObject:nil afterDelay:0.1];//延迟加载,执行
modifyConstant,0.1秒之后再 改变约束值!
}- (void)modifyConstant//把修改的代码放在一个房里里!{ self.top.constant+=100; self.height.constant+=100;}@end
这样就可以解决在 viewDidLoad中 修改 约束值失败的问题了!
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'}

我要回帖

更多关于 autolayout 居中约束 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信