• 问题总会出现,不过解决问题的方法也会出现!!!

自动布局

自动布局 小雨 808次浏览 已收录 0个评论

00-屏幕适配概述[了解] 屏幕适配简介

• 在以前的iOS程序中,是如何设置布局UI界面的?

• MagicNumber -> autoresizingMask -> autolayout
• iphone1-iphone3gs时代 window的size固定为(320,480) 我们只需要简单计算一下相对位置就 好了
• iphone4-iphone4s时代 苹果推出了retina屏 但是给了码农们非常大的福利:window的size不变
• iphone5-iphone5s时代 window的size变了(320,568) 这时AutoresizingMask派上了用场(为什
么不用Autolayout? 因为还要支持ios5)
• iphone6+时代 window的width也发生了变化(相对5和5s的屏幕比例没有变化) 终于是时候抛弃 AutoresizingMask改用Autolayout了(1.不用支持ios5了 2. 相对于屏幕适配的多样性来说 autoresizingMask也已经过时了)
• 直到iphone6发布之后 我知道使用Autolayout势在必行了

补充Xcode版本信息

Xcode4.2: 2011年10月13日 –开始支持(iOS5-iPhone4s)

Xcode4.5:2012年9月20日-开始支持(iOS6-iPhone5)

Xcode5.0: 2013年9月18日 — 开始支持(iOS7-iPhone5s)

Xcode6.0:2014年9月17日-开始支持(iOS8-iPhone6)

什么是Autolayout

• Autolayout是一种“自动布局”技术,专门用来布局UI界面的
• Autolayout自iOS 6开始引入,由于Xcode 4.5 的不给力,当时并没有得到很大推广
• 自iOS 7(Xcode 5)开始,Autolayout的开发效率得到很大的提升
• 苹果官方也推荐开发者尽量使用Autolayout来布局UI界面
• Autolayout能很轻松地解决屏幕适配的问题

AutoSesizing与Autolayout

• Autoresizing
• 在Autolayout之前,有Autoresizing可以作屏幕适配,但它仅仅能够约束父子关系,局限性较 分区第十天屏幕适配的第1页
• 在Autolayout之前,有Autoresizing可以作屏幕适配,但它仅仅能够约束父子关系,局限性较 大,有些任务根本无法完成.
• 相比之下,Autolayout的功能比Autoresizing强大很多
• Autolayout的2个核心概念
• 参照
• 约束

A01-Autoresizing基本使用[了解]

1. 在storyboard中,autolayout和autoresizing二者只能用其一
先去掉outlayout,

自动布局
2. 学习Autoresizing分为两步:

a. 学习周围的四根线
i.自动布局
b. 学习中间两根线
i.自动布局

3. 学习周围四根线

a. 用途:用来控制当前控件和父控件的距离的
b. 如果勾选左边线条,代表当前控件与父控件的左边的距离固定,其他依次类推
c. 举例:四个红色方块在控制器view内部,要求无论控制器view如何变化,四个红色方块
永远都在控制器view的的四个角上

d.自动布局
e. 设置
i.自动布局
f. 同理设置其他三个角的红色view自动布局自动布局自动布局

使用storybord的预览功能:自动布局自动布局

当鼠标移动上去,可以对屏幕进行旋转 自动布局

点击它,就可以旋转屏幕,旋转后自动布局
还可添加其他屏幕的预览自动布局

点击iPhone 3.5-inch

自动布局
4. 中间两条线约束子控件是否随父控件的宽高变化而变化
a. 如果勾选了中间水平方向这条线,则子控件宽度,随父控件宽度的变化而变化.
b. 如果勾选了中间垂直方向这条线,则子控件高度,随父控件高度的变化而变化.
c. 要求:红色控件在蓝色控件内部,(蓝为父,红为子),红色控件与蓝色控件上下左右的距
离不变, 红色控件随着蓝色控件的宽度的变化而变化,点击按钮让蓝色控件的 宽高变大

d.自动布局
e. ViewController的实现文件

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *blueView; - (IBAction)bigger;
@end
@implementation ViewController
- (IBAction)bigger {
CGRect frame = self.blueView.frame; frame.size.width += 10; frame.size.height += 10; self.blueView.frame = frame;
}
@end

运行看结果:红色不会随蓝色宽高而变化
f.勾上水平线
自动布局
运行看结果:红色的宽度随,蓝色的宽度变化而变化
自动布局自动布局
运行看结果:红色的高度随,蓝色的高度变化而变化
自动布局

A02-代码中使用autoresizing[了解]

需求:搞两个控件,一个蓝色一个红色,形成父子关系,蓝色是父控件,红色是子控件.
让红色控件永远在蓝色的底部,并且红色的宽度必须随着蓝色的变化而变化
代码中是通过 autoresizingMask 属性来设置autoresizing的 autoresizingMask 是一个枚举类型 有以下取值:

没有约束
UIViewAutoresizingNone = 0,
本控件与其父控件左边的间距是可变的,也就是说本控件与其父控件右边是固定的 此处设置外部四个线正好与storyboard中相反 UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
当前控件的宽度可变,对应着storyboard中中间的水平线 UIViewAutoresizingFlexibleWidth = 1 << 1,
本控件与其父控件右边的间距是可变的,也就是说本控件与其父控件左边是固定的 UIViewAutoresizingFlexibleRightMargin = 1 << 2,
本控件与其父控件顶部的间距是可变的,也就是说本控件与其父控件底部是固定的 UIViewAutoresizingFlexibleTopMargin = 1 << 3,
当前控件的高度可变,对应着storyboard中中间的垂直的线 UIViewAutoresizingFlexibleHeight = 1 << 4,
本控件与其父控件底部的间距是可变的,也就是说本控件与其父控件顶部是固定的 UIViewAutoresizingFlexibleBottomMargin = 1 << 5

注意: 代码设置的autorezing四周的线段和storyboard的线是相反的 左边是可拉伸的,也就是说右边是固定的
viewController.m文件:

#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) UIView *blueView;
@end
@implementation ViewController /*
搞两个控件,一个蓝色一个红色,形成父子关系,蓝色是父控件,红色是子控件. 让红色控件永远在蓝色的底部,并且红色的宽度必须随着蓝色的变化而变化
*/
- (void)viewDidLoad { [super viewDidLoad];
// 添加蓝色view

// 添加蓝色view
UIView *buleView = [[UIView alloc] init]; buleView.frame = CGRectMake(10, 100, 200, 200); buleView.backgroundColor = [UIColor blueColor]; [self.view addSubview:buleView];
self.blueView = buleView;
// 添加红色view
UIView *redView = [[UIView alloc] init]; redView.frame = CGRectMake(50, 100, 100, 100); redView.backgroundColor = [UIColor redColor]; [buleView addSubview:redView];
// 添加按钮
UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd]; btn.center = CGPointMake(150, 50);
[self.view addSubview:btn];
// 为按钮添加时间
[btn addTarget:self action:@selector(bigger) forControlEvents:UIControlEventTouchUpInside];
// 使用autoresizing建立约束 /*
强调:Flexible 可变的
没有约束
UIViewAutoresizingNone = 0,
本控件与其父控件左边的间距是可变的,也就是说本控件与其父控件右边是固定的 此处设置外部四个线正好与storyboard中相反 UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
当前控件的宽度可变,对应着storyboard中中间的水平线 UIViewAutoresizingFlexibleWidth = 1 << 1,
本控件与其父控件右边的间距是可变的,也就是说本控件与其父控件左边是固定的 UIViewAutoresizingFlexibleRightMargin = 1 << 2,
本控件与其父控件顶部的间距是可变的,也就是说本控件与其父控件底部是固定的 UIViewAutoresizingFlexibleTopMargin = 1 << 3,
当前控件的高度可变,对应着storyboard中中间的垂直的线 UIViewAutoresizingFlexibleHeight = 1 << 4,
本控件与其父控件底部的间距是可变的,也就是说本控件与其父控件顶部是固定的 UIViewAutoresizingFlexibleBottomMargin = 1 << 5 */ // 多中约束使用连接符: "|" redView.autoresizingMask = UIViewAutoresizingFlexibleT opMargin|UIViewAutoresizingFlexibleWidth; }
 - (void) bigger { // 让蓝色的view宽高变大 CGRect frame = self.blueView.frame; frame.size.width += 20; frame.size.height += 10; self.blueView.frame = frame; }

 

A03-autoresizing弊端[了解]

只能设置当前控件和父控件之间的约束,不能设置当控件与兄弟控件之间的约束 要求:拖入两个view并设置view宽度为130, 要求两个View距离左右和顶部永远是20

自动布局 设置: 》设置A控件距离左边顶部固定, 设置B控件距离右边顶部固定, 运行查看效果自动布局自动布局自动布局

》设置A,B控件内部是可拉伸的, 运行查看效果自动布局自动布局自动布局

》无论如何Autosizing无法满足需求, 因为Autosizing是相对父控件计算的, 不能单独设置两个 控件之间的约束条件

B01-Autolayout的基本使用[掌握]

1. Autolayout基本概念

》讲解如何打开Autolayout(勾选Use Auto Layout)

为了我们能够使用autolayout,必须勾选, 为了更清楚的认识autolayout, sizeclass 先不要勾选.自动布局

>没有使用auturesizing/autolayout时是设置frame , 设置frame其实就是告诉系统控件的 X/Y/宽/高.

>以前可以通过frame直接设置控件的X/Y/宽/高.

>以前可以通过auturesizing间接设置控件的X/Y/宽/高.

>so使用autolayout时也是间接设置控件的X/Y/宽/高即可

》讲解故事版底部几个按钮作用:第一个按钮:自动布局
这个按钮是用来设置对齐方式的:自动布局
用来设置两个兄弟控件A与B, A最左边与B的最左边的距离自动布局

用来设置两个兄弟控件A与B, A最右边与B的最右边的距离自动布局

用来设置两个兄弟控件A与B, A顶部与B的顶部的距离自动布局

用来设置两个兄弟控件A与B, A底部与B的底部的距离自动布局
用来设置两个兄弟控件A与B, A中心的x坐标与B中心的x坐标的距离自动布局

用来设置两个兄弟控件A与B, A中心的y坐标与B中心的y坐标的距离
自动布局
设置子控件中心的x坐标距离父控件中心x坐标的距离自动布局

设置子控件中心的y坐标距离父控件中心y坐标的距离

总结:这些都是为了设置控件的位置信息

第二个按钮(Pin):可以认为是设置控件位置,尺寸的
从上往下:自动布局
不仅可以autoresizing外部四根线那样设置子空间与父控件的之间的间距,还可以设置兄弟空间之间的间距

它有上下左右四个方向自动布局
设置当前控件的固定宽高自动布局
设置多个控件的宽高相等自动布局
设置控件之间的对齐方式
第三个按钮:自动修正: 当控件的约束出现错误或警告时候使用自动布局
注意:使用这个修正功能并不能保证每次都按你的意愿进行修正,而是按照xcode认为是正确的方式进行修正 第四个按钮:
很少使用,一般都是默认情况自动布局
sibling 兄弟姐妹

ancestor 祖先

descendant 后代

自动布局

勾选表示:当兄弟控件或祖先控件与该控件有关于szie(尺寸) 的约束关系的时候,但调整该控件的大小 的时候,与之有约束关系的控件随之变化自动布局
勾选表示:当后代(子孙)控件与该控件有关于szie(尺寸) 的约束关系的时候,但调整该控件的大小的时 候,与之有约束关系的控件随之变化

练习1

1.让子控件永远居中, 宽高永远100

1.0 拖入一个控件设置尺寸为100,100 ,位置随便放置 1.1设置距离父控件中心自动布局
添加完毕后自动布局
这里会出现一个红色的箭头: 1.2 红色箭头:
storyboard当缺少约束或约束冲突时候,会出现红色的箭头 分区第十天屏幕适配的第18页
storyboard当缺少约束或约束冲突时候,会出现红色的箭头 分析:我们知道要设置一个控件的约束信息,必须提供位置和尺寸
现在在所设置水平与垂直居中仅仅是设置了蓝色方块的位置信息,还没有设置蓝色方块的宽高,因为缺 少约束所以出现红色箭头
1.3.设置宽高自动布局
添加完毕后自动布局
1.4 黄色箭头:黄色箭头代表当前控件的X或Y或宽或高和autulayout约束的不一致 但这个并不影响控件运行的位置和尺寸,控件运行的时候会按照约束的位置和尺寸来展示控件 但是有时候我们为更加好看,需要控件进行修正,修正有两种方式
1.4.1 第一种方式:

自动布局自动布局自动布局
修复完毕:

自动布局

1.4.2 :通过command + z 可以回退刚刚设置

自动布局
1.4.3 第二种方式修复警告:
自动布局
修复后

自动布局
1.4.5 红色箭头出现是由于缺少约束或约束冲突导致的,我刚才仅仅是验证了缺少约束,接下来验证约束冲 突
在storybaord中可以为一个控件相同的约束添加多次自动布局

添加后:自动布局
这里红色箭头出现的原因是因为一个约束 width == 100 而另外一个约束 width >= 200
约束冲突导致的 1.4.6 修复红色箭头自动布局自动布局自动布局

修复完成.

总结:上面的练习让我们学会了:

1.通过layout设置控件水平和垂直居中
2.通过layout设置控件的尺寸
3.红色箭头:表示缺少约束或约束冲突
4.如何修复红色箭头
5.黄色箭头:表示layout的约束控件的x/y/w/h 与控件在storybaord中的x/y/w/h 不一致
6.如何修复黄色箭头

2.需求:让控件居中,并且距离上下左右都是50

2.1 拖入一个view,背景设置为蓝色,调整尺寸

自动布局
设置距离父控件上下左右的宽度

2.2.设置距离父控件上下左右距离

2.2.1 设置顶部的距离:

自动布局
设置后:

自动布局
我们刚才看到设置时候可以进行下拉选择

自动布局
怎么证实Top Layout Guide就是顶部的状态栏或导航栏呢 自动布局


我怎么知道这个TopLayout Guide就是设置时候,所选的那个TopLayout Guide

我们知道在storyboard中控件导航中可以修改控件在stroyboard中的名称

自动布局
编辑完毕再次点击enter键退出编辑状态

自动布局
现在要求设置距离父控件的顶部50

所以要:删除刚才设置约束
2.2.1.1 删除约束第一种方式

自动布局
2.2.1.2 删除约束的第二种方式:
自动布局
第三种方式:

自动布局
重新添加:自动布局
添加后:
自动布局
2.2 设置距离父控件左边的距离

自动布局
设置后:

自动布局
删除掉刚才的约束
自动布局
重新设置

自动布局

设置后:

自动布局
同理我们设置底部和右边
自动布局
设置完毕后:

运行:
竖屏:自动布局
横屏:自动布局


都没有问题: 另外当子控件距离父控件的上下左右四个方向的距离都确定了,那么这个子控件的位置和尺寸也就确定
所以可以不设置子控件在父控件的中心

自动布局
删除后:

自动布局
再次运行,效果之前一样.
总结:这里我们学会了

1.如何设置控件距离父控件四周的距离约束

>设置控件距离控制器View的顶部有50的间隙(注意, 系统默认是距离状态栏, 需要手动修改)

>设置控件距离控制器View的左边有50的间隙(注意,Xcode6之后, 系统会默认添加16的间隙, 如果 不想要可以去掉magins)

2.如果修改控件stroyboard中名称

3.如何删除控件上约束

B02-AutoLayout的其他使用[掌握]

练习2

第一题: 控制器的view内部有红蓝两个view,红色的view与蓝色的view时兄弟关系.

要求:红色的view距离控制器的view左边20固定,底部20固定,高度100固定

蓝色view与控制器view右边20底部20,高度与红色view相同,

蓝色view与红色的view之间的间隙为20

当有多个view的时候,建议一个一个搞,当多同时搞的话就容易搞混

 

1.0 拖入一个view,x,y 为 0,0 调整它的宽高为100,颜色设置为红色;然后复制一个出来,调整颜色
为蓝色, 把着两个view拉到控制view的下面,如图:自动布局
1.1 设置红色view:

>设置距离控制器View左边20固定 (X)

>设置距离控制器View底部20固定 (Y)

>设置红色控件的高度等于100 (高度)

自动布局
设置完毕:自动布局
1.2 设置蓝色view

>设置距离控制器View右边20固定 (X)

>设置距离控制器View底部20固定 (Y)

自动布局

1.3 设置红色view与蓝色view之间的关系

设置红色和蓝色宽度一样 (宽度)
设置红色和蓝色高度一样 (高度)

自动布局自动布局自动布局自动布局

此时显示蓝色与红色的view缺少x的位置或宽度

自动布局
我们设置蓝色的view与红色viwe宽度相同,但是红色的view的宽度我们没设置,

所以现在红色的view的宽度与蓝色的view的宽度都无法确定
但是当我确定了红色的view与蓝色的view之间的间距的时候

系统会根据约束动态的计算出红色和蓝色view的宽度
w =(控制view的W-20-20-20)/2
接下来添加蓝色的view与红色view之间的间距,

注意此时不要同时选中两个view,只需要选中其中一个就OK了

自动布局

设置完毕后,红色的箭头消失:

1.3.2 进行修复
自动布局
1.3.3 修正后,运行

竖屏:

自动布局
横屏:
自动布局
都是OK的
总结:我们学会了

1.如何设置兄弟控件的之间关系

2.同时修正多个控件的frame

1.4 补充: 这个练习也可以通过另外一种方式来限制蓝色view的高度,和y坐标

1.4.1.当我们设置蓝色view的顶部与底部与红色的view对齐,那么蓝色的view的高度,y坐标就确定
1.4.2 删除蓝色高度与y坐标的约束自动布局
删除后
自动布局
1.4.3 通过拖线的方式设置蓝色view与红色view顶部与底部对齐

第一步:按住control 键从蓝色view向红色的view拖线自动布局
弹出如下视图
自动布局自动布局
运行测试

总结:

1. 我们学会了如何通过拖线的方法设置不同控件之间的约束关系

2.我们对通过约束设置控件的x/y/w/h有了更深刻的了解

第二题:

控制器的view中有红色View和蓝色View
要求 蓝色view距离控制器的view顶部以及左右都是20,高度为100
红色的view与控制器view的右边的间距也为20 红色view在蓝色view下方,红色view与蓝色view之间的间
隔为20 红色view与蓝色view的高度相同,宽度是蓝色view的一半

2.1 拖入一个view ,调整其位置尺寸(20,20,280,100),背景颜色修改为蓝色,拷贝一份到蓝 色view下面,设置背景颜色为红色.修改控件导航的view的名称自动布局
2.2 设置蓝色的VIew

设置距离控制器的view上下左右都是20

设置高度为100
自动布局
设置完毕后,蓝色view的x/y/w/h都有了,所以不会出现红色的箭头

2.3 设置蓝色的view
第一种设置方法:

1. 设置蓝色的view与父控件右边的距离是20(x)自动布局
2.设置蓝色的view与红色的view垂直间距20(y)
自动布局
3.设置蓝色的view与红色的view的高度相同(H)

4.设置蓝色的view是红色view的宽度相同(W)自动布局
现在红色的view与蓝色的view宽度相同不是我们想要的,我们要的是红色的view是蓝色 view宽度的一半
4.1 修改红色与蓝色宽度相同的约束
自动布局

修改后自动布局
修复:自动布局
更新后自动布局
运行:竖屏自动布局

横屏:自动布局

第二种方式:

可以不设置红色view距离控制器view右边为20,而设置红色的view与蓝色的view右 对齐

1.删除红色view距离控制器view右边为20的约束(蓝色的x)自动布局

删除后自动布局
2.添加红色的view与蓝色的view右对齐(蓝色的x)
自动布局
添加后,红色箭头消失, 运行与之前相同,都OK.

总结:

1.学会了如何设置一个控件的宽度是另外的宽度的一半

2.学会了如何设置尾部对齐

3.加深了设置控件的layout就是设置控件的x/y/w/h的认识.

B03-AutoLayout的使用技巧[掌握]

需求1: 使用一张图片作为主页界面,无论是在4s还是5/5s上都可以正常显示

1.0 创建项目去掉sizeclasses,拖入图片,storyboard中拖入imageView,设置imageView的图片 , 完成后如图所示:

自动布局
如果在5/5s就按照这中防守展示,如果在4s上只展示中间的一部分

自动布局
设置完图片运行在4s,结果:

自动布局
底部按钮没显示完全
请问应该如何设置:

3.1 我的想法就是通过autolayout设置imageView居中显示

自动布局
添加完毕后运行到4s上,图片尺寸明显过大

自动布局

3.2 这个因为图片放在1x的位置,为给它放到2x区域

自动布局
再次运行:4s上OK

自动布局
5s竖屏也OK
自动布局
通过我们设置现在可以了,达到我们目标了

3.3 回到stroybaord,你能发现什么问题吗?

自动布局
这是因为对于imageView,label,button,textField 等有内容的控件,无需设置他们宽高,系统会根据 内容计算
控件的大小.
举例说明:拖入一个新的viewController,在控制器的view上拖入一个imageView,调整位置和尺 寸
添加水平居中和垂直居中的约束后,如下图
自动布局
这里报缺少约束的错误是因为图片中没有内容,当imageView中没有内容的时候,系统无法确定 imageView的大小
给imageView设置一张图片,设置后:

自动布局
当imageView,图片的时候,系统会根据图片的大小来确定imageView的大小.
你现在可以理解为什么我把1x的图片拖入到2x的位置就没有问题了吗?

因为当只有1x位置有图片的时候,当retain屏幕需要展示展示这个图片的时候,会对1x的图片放 大两倍后进行展示,所以刚开始时候,由于系统对图片进行放大所有图片展示的过大.

而当我它拖入到2x的时候,在retain屏幕上不会对其放大所以没有问题

3.3.2 接着我们在以label为例进行说明:

自动布局
运行起来文字是垂直居中的

自动布局
如何根据文字的内容确定文本框的大小呢?
第一种方式:通过代码方式,使用NSString 提供方法,动态计算出文字所占的大小,然后设置给 label
第二种方式:通过autolayout

自动布局
运行:

自动布局
这样要比我们使用代码搞方便很多.

需求2 : 使用一张图片作为主页界面,主界面上有按钮的位置添加一个按钮控件,无论是在4s还 是5/5s上都可以正常显示,如图

自动布局
2.1.拖入按钮,去掉文字设置背景颜色

自动布局

由于storyboard中的界面就是4.0的所以运行在5s上肯定没有问题 我来看一下运行在4s的情况.

自动布局
这个问题该如何解决:

分析:在没有使用autoLayout的时候,系统安装按钮的x,y固定左边展示图片的,由于4s与5屏幕高 度不一样导致4s上显示不正确,

我们再来看,无论在4s还是在5s上按钮距离垂直中线的位置是不变的
自动布局
我们可以设置,按钮距离控制器view的中线对齐

自动布局
在运行:
自动布局
此时按钮,按钮的位置OK了,但是 按钮变小了,设置按钮宽高约束

自动布局
运行到4s上测试:

自动布局
位置和尺寸都OK. 运行到5s上测试:也是OK的
自动布局
其他的按钮,你们做为作业,自己搞下吧,自动布局只有多操作才能熟练.

B04-Autolayout约束的代码创建[了解]

• 一个NSLayoutConstraint对象就代表一个约束
• 创建约束对象的常用方法

+(id)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 :常量
对照storyboard说明:

自动布局
使用代码创建这个约束:

NSLayoutConstraint *blueTop = [NSLayoutConstraint constraintWithItem:蓝色的View
						  attribute:顶部
						  relatedBy:等 于
						  toItem: 父控件
						  attribute:顶部
						  multiplier:1
						  constant:100];

使用完整代码:

NSLayoutConstraint *blueTop = [NSLayoutConstraint constraintWithItem:self.blueView
						  attribute:NSLayoutAttributeTop
						  relatedBy:NSLayoutRelationEqual
						  toItem:self.superView
						  attribute:NSLayoutAttributeTop
						  multiplier:1
						  constant:100];
attribute:参数是一个枚举,取值如下(iOS8新增的未列出)
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1, //左侧
NSLayoutAttributeRight, //右侧
NSLayoutAttributeTop, //上方
NSLayoutAttributeBottom, //下方
NSLayoutAttributeLeading, //首部
NSLayoutAttributeTrailing, //尾部
NSLayoutAttributeWidth, //宽度
NSLayoutAttributeHeight, //高度
NSLayoutAttributeCenterX, //X轴中心
NSLayoutAttributeCenterY, //Y轴中心
NSLayoutAttributeBaseline, //文本底标线NSLayoutAttributeNotAnAttribute = 0//没有属性};
说明: 其中leading与left trailing与right 在正常情况下是等价的 但是当一些布局是从右至左时(比如阿拉伯文) 则会对调,换句话说就是只用left和right就好了
relatedBy:参数也是一个枚举值,取值如下:
typedef NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1, //小于等于
NSLayoutRelationEqual = 0, //等于
NSLayoutRelationGreaterThanOrEqual = 1, //大于等于 };

• 自动布局有个核心公式
obj1.property1 =(obj2.property2 * multiplier)+ constant value

B05-AutoLayout约束的添加规则[了解]

在创建约束之后,需要将其添加到作用的view上

在添加时要注意目标view需要遵循以下规则:
1)对于两个同层级view之间的约束关系,添加到它们的父view 上

自动布局
2)对于两个不同层级view之间的约束关系,添加到他们最近的共 同父view上

自动布局
3)对于有层次关系的两个view之间的约束关系,添加到层次较高 的父view上

自动布局
4)只与自己本身有关系,添加到自己上(如固定的宽或高)

B06-使用代码添加layout约束[了解]

• 代码实现Autolayout的步骤
• 利用NSLayoutConstraint类创建具体的约束对象
• 添加约束对象到相应的view上

- (void)addConstraint:(NSLayoutConstraint *)constraint;
- (void)addConstraints:(NSArray *)constraints;

• 代码实现Autolayout的注意点
• 要先禁止autoresizing功能,设置view的下面属性为NO

view.translatesAutoresizingMaskIntoConstraints = NO;

• 否则报错:
2015-03-11 21:59:02.845 B05-代码中使用autolayout[了解][2564:308089] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don’t want. Try this: (1) look at each constraint and try to figure out which you don’t expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you’re seeing NSAutoresizingMaskLayoutConstraints that you don’t understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
• 添加约束之前,一定要保证相关控件都已经在各自的父控件上
• 否则程序崩溃,错误信息
2015-03-11 22:00:50.196 B05-代码中使用autolayout[了解][2582:309415] The view hierarchy is not prepared for the constraint: When added to a view, the constraint’s items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled.
翻译:当添加一个约束到一个view上的时候,必须保证这个view是 控制器view的子孙
• 不用再给view设置frame

B07-代码中使用Autolayout练习[了解]

控制器的view中有红色View和蓝色View

要求:
蓝色view距离控制器的view顶部以及左右都是20,高度为 100
红色的view与控制器view的右边的间距也为20
红色view在蓝色view下方,红色view与蓝色view之间的间 隔为20
红色view与蓝色view的高度相同,宽度是蓝色view的一半 使用纯代码

ViewController.m文件:

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 创建蓝色view
UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor];
// 创建红色的view
UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor];
// 添加约束准备
// 1.子控件必须添加到父控件中
[self.view addSubview:blueView];
[self.view addSubview:redView];
// 2.禁用autoresizing
// 设置父控件无效
// self.view.translatesAutoresizingMaskIntoConstraints = NO;
blueView.translatesAutoresizingMaskIntoConstraints = NO; redView.translatesAutoresizingMaskIntoConstraints = NO;
// 3.为蓝色的view添加约束
// 3.1顶部约束
NSLayoutConstraint *blueTop = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:20];
// 添加约束
[self.view addConstraint:blueTop]; //
// 3.2左边约束
NSLayoutConstraint *blueLeft = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:20];
// 添加约束
[self.view addConstraint:blueLeft];
// 3.3右边约束
NSLayoutConstraint *blueReight = [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20];
分区第十天屏幕适配的第68页
attribute:NSLayoutAttributeRight multiplier:1.0 constant:-20]; // 添加约束
[self.view addConstraint:blueReight];
// 3.4高度约束
NSLayoutConstraint *blueHeight = [NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100];
[blueView addConstraint:blueHeight];
// 设置红色view上的约束
// 4.1设置红色view顶部距离蓝色view底部20
NSLayoutConstraint *redTop = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:20];
// 添加约束
[self.view addConstraint:redTop];
// 4.2设置红色view的高度与蓝色view相同
NSLayoutConstraint *redHeight = [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0];
// 添加约束
[self.view addConstraint:redHeight];
// 4.3设置红色view的宽度度是蓝色view宽度的一半
NSLayoutConstraint *redWidth = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0];
// 添加约束
[self.view addConstraint:redWidth];
// 4.4 设置红色的view与蓝色的view右边对齐
NSLayoutConstraint *redRight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0];
// 添加约束
[self.view addConstraint:redRight];
}

B08-VFL语言[了解]

1.什么是VFL语言

• VFL全称是Visual Format Language,翻译过来是“可视化格式语言”
• VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言

自动布局
2.VFL示例

• 基本格式:

• H:|-水平间距-[左1(宽度)]-水平间距-[左2(宽度)]-水平间距-|
• V:|-竖直间距-[上1(宽度)]-竖直间距-[上2(宽度)]-竖直间距-|

• 说明:冒号前面:”H”表示水平方向,”V” 竖直方向. 如果是”H”,那么冒号后面是从左到右 控件的顺序,每一个控件都需要使用”[]”扩起来,控件后面的小括号的浮点数表示控件 的宽度,两个控件中间 -数值- ,表示水平方向的间距; 如果是”V”,那么冒号后面是从上 到下控件的顺序,每一个控件都需要使用”[]”扩起来,控件后面的小括号的浮点数表示 控件的高度,两个控件中间 -数值- ,表示竖直方向的间距. “|” 表示父控件的边界.

 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 分区第十天屏幕适配的第70页

H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|

• 水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔 默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘 的间距都是默认宽度。(竖线“|” 表示superview的边缘)
3.VFL的使用
• 使用VFL来创建约束数组

+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;

• format :VFL语句
• opts :约束类型(水平或垂直方向上的多个控件的对齐方式)
• metrics :VFL语句中用到的具体数值
• views :VFL语句中用到的控件
• 创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义
NSDictionaryOfVariableBindings(…)

B09-VFL练习[了解]

1.控制器的view中有红色View和蓝色View

要求:
蓝色view距离控制器的view顶部以及左右都是20,高度为 100
红色的view与控制器view的右边的间距也为20
红色view在蓝色view下方,红色view与蓝色view之间的间 隔为20
红色view与蓝色view的高度相同,宽度是蓝色view的一半 使用VLF语言

@implementation ViewController /*
1.控制器的view中有红色View和蓝色View
要求 蓝色view距离控制器的view顶部以及左右都是20,高度为100 红色的view与控制器view的右边的间距也为20 红色view在蓝色view下方,红色view与蓝色view之间的间隔为20 红色view与蓝色view的高度相同,宽度是蓝色view的一半 使用VLF语言
*/
- (void)viewDidLoad { [super viewDidLoad];
// 创建蓝色view
UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; // 创建红色的view
UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor];
// 添加约束准备
// 1.子控件必须添加到父控件中
[self.view addSubview:blueView]; [self.view addSubview:redView]; // 2.禁用autoresizing
// 设置父控件无效
// self.view.translatesAutoresizingMaskIntoConstraints = NO;
blueView.translatesAutoresizingMaskIntoConstraints = NO; redView.translatesAutoresizingMaskIntoConstraints = NO;
// 添加水平方向的约束
NSArray *hCons = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-
[blueView]-20-|" options:NSLayoutFormatAlignAllTop metrics:nil views: @{@"blueView":blueView}];
[self.view addConstraints:hCons]; // 添加垂直方向约束
NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20- 分区第十天屏幕适配的第72页
NSArray *vCons = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20- [blueView(100)]-20-[redView(==blueView)]" options:NSLayoutFormatAlignAllRight metrics:nil views:@{@"blueView":blueView,@"redView":redView}];
[self.view addConstraints:vCons];
// 添加红色view宽度的约束
NSLayoutConstraint *redW = [NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0.0];
[self.view addConstraint:redW];
// VFL 不支持乘法
// NSArray *rCons = [NSLayoutConstraint constraintsWithVisualFormat: @"H:[redView(==blueView * 0.5)]" options:NSLayoutFormatAlignAllTop metrics:nil views: @{@"blueView":blueView,@"redView":redView}];
// [self.view addConstraints:rCons];
}
@end

B10-Masonry[理解]

Masonry 概述
○ Masonry,“一个轻量级的布局框架,采用更”优雅”的语法封装自动布局”,不需要使
用XIB和Storyboard, 并具有高可读性 而且同时支持 iOS 和 Max OS X Masonry尤其适合习惯纯代码开发的开发者 ,在iPhone6发布后引发的适配潮中 Masonry一定
可以助你一臂之力
○ 框架下载地址: https://github.com/Masonry/Masonry
○ 拿到任何一个框架不是马上去看的源代码是怎么实现的,而是先用起来,从最简单的使用
开始,一个框架都会带有示例程序,我们可以照葫芦画瓢,先看好用不好用.
○ 常用属性含义(View+MASShorthandAdditions.h)

/* View+MASShorthandAdditions中属性与NSLayoutAttrubute的对照表如下 Masonry NSAutoLayout 说明
left
top
right
bottom
leading NSLayoutAttributeLeading 首部 trailing NSLayoutAttributeTrailing 尾部
width NSLayoutAttributeWidth 宽 height NSLayoutAttributeHeight 高 centerX NSLayoutAttributeCenterX 横向中点 centerY NSLayoutAttributeCenterY 纵向中点 baseline NSLayoutAttributeBaseline 文本基线
注意:iOS8中新增的属性Masonry暂时还不支持(提示:现阶段我们开发的APP要支持 ios6,ios7 所以可以忽略)
*/

Masonry基本使用
○ 利用代码实现在控制器上添加一个控件, 宽高等于200并且永远在屏幕中间
创建项目
导入masonry框架 根据示例程序来写
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
NSLayoutAttributeLeft 左侧 NSLayoutAttributeTop 上侧 NSLayoutAttributeRight 右侧
NSLayoutAttributeBottom 下侧
还支持CGPoint CGSize UIEdgeInsets */

Masonry练习
○ 在控制器上添加一个控件,距离控制器View上下左右各20
方式一逐个设置 make.top.equalTo
方式二连续设置 make.top.left
make.bottom.and.right.equalTo

/*
注意:这里的and和with 其实这两个函数什么事情都没做
and和with方法直接 return self;
*/

方式三一次性设置 make.edges.equalTo
○ 实现PPT练习2
控制器的view中有红色View和蓝色View
要求 蓝色view距离控制器的view顶部以及左右都是20,高度为100 红色的view与控制器view的右边的间距也为20 红色view在蓝色view下方,红色view与蓝色view之间的间隔为20 红色view与蓝色view的高度相同,宽度是蓝色view的一半
代码实现:

// 创建蓝色view
UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; // 创建红色的view
UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor];
// 添加约束准备
// 1.子控件必须添加到父控件中
[self.view addSubview:blueView]; [self.view addSubview:redView];
设置blueView的约束
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.equalTo(20); make.right.equalTo(-20); make.height.equalTo(100);
}];
[redView mas_makeConstraints:^(MASConstraintMaker *make) {
//1.设置红色的view的宽
//方式1
// make.width.equalTo(blueView.width).multipliedBy(0.5);
//方式2
make.left.equalTo(blueView.centerX);
//2.设置红色的view的高
make.height.equalTo(blueView.height);
//3.设置距离蓝色view的底部20
make.top.equalTo(blueView.bottom).offset(20);
//4.设置右边与蓝色的view对齐
make.right.equalTo(blueView.right);
}];

快速入门文章 http://adad184.com/2014/09/28/use-masonry-to-quick-solve-autolayout/
iOS8新特性介绍: https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS8.html#//apple_ref/doc/uid/TP40014205-SW1

B11-AutoLayout中使用动画

1.创建项目,去掉sizeclasses,拖入一个view,设置位置尺寸为(0,0,100,100),背景颜色设置为紫色

自动布局
2.为紫色的view添加约束

自动布局
3.使用了autolayout 就不能使用frame来调整图形位置,如果想通过代码改变图形的位置,只能通过改变约束实现,storybaord中的约束与控件一样也是可以与代码文件进行连线的.

3.1 拖线

自动布局
3.2设置约束名称 松手后回出现

自动布局
3.3 按照同样的方法把水平方向的也拖过来

3.4 拖入一个按钮,并进行Action连线

自动布局

4 回到控制中写代码

4.1 验证能否通过修改约束改变图形的位置

- (IBAction)layoutAnimation {
// 水平方向移动图形
self.hConstraint.constant += 20; }

4.2 运行测试:可以改变图形的位置
4.3 按照frame的方式添加动画:

// 添加动画代码
[UIView animateWithDuration:2 animations:^{
// 水平方向移动图形
self.hConstraint.constant += 100;
}];

对不起,让你失望,这种方式下没有动画效果.因为约束并不是直接影响图形的位置,设置完毕后系统
会根据约束来计算图形的位置和大小
4.4 在动画代码外边调整约束,在动画代码内部调用layoutIfNeeded方法,该方法表示按照约束重新 布局界面

- (IBAction)layoutAnimation {
// 水平方向移动图形
self.hConstraint.constant += 100;
// 添加动画代码
[UIView animateWithDuration:2 animations:^{
// 将需要执行动画的代码写到这里面
//调用layoutIfNeeded方法之后, 它会依次更新该控件所有子控件以及自己的约束
//如果用pinkView调用layoutIfNeeded方法, 会更新pinkView/以及它的所有子控件
[self.view layoutIfNeeded]; }];
}

4.5 测试,确实可以执行动画了.
4.6请自己测试 pinkView/以及它的所有子控件/以及它的父控件

C01-sizeclasses[掌握]

基本概念

1.在iOS7之前要开发iPhone和iPad通用版本需要创建两个
Storeboard(Main_iPhone.Storeboard / Main_iPad.Storeboard);
2.iOS8中新增了SizeClasses特性, 它是对当前所有iOS设备尺寸的一个”抽象”。由于当前苹果设备尺寸较多, 如果没有SizeClasses开发人员会和Android一样累死, 所以苹果为了解决这个为 题推出了SizeClasses.
3. SizeClasses将屏幕的宽高分成三种情况(Compact(紧凑),Regular(正常),Any(任意), 所以一共有9个类别;
在设置 Size Class 的时候页面会有提示。比如宽为 Compact 高为 Any 的情况,提示为 3.5-inch、4-inch、4.7-inch的横竖状态下的屏幕:

自动布局
这使得我们可以单独针对每一种情况单独布局约束

苹果官网文档举了一些例子:

自动布局自动布局自动布局自动布局自动布局

Size Classes的使用 》

如何打开SizeClasses
1.使用xcode6创建通用项目,默认就启动了Size Classes

2.只有开启了autolayout 才能使用size Classes
自动布局
3.Size Classes开启的时候,storyboard下面会出现Size Classes相关的工具条

自动布局
勾选 Size Classes

自动布局
》SizeClasses9宫格的含义 (参考图片)

点击上面的工具条就会显示,

自动布局
接下来我们一一说明
1. 宽高都是(Compact)紧凑的,就是.3.5,4,4.7英寸的iphone的横屏

自动布局
2.宽度是(any)任意的,高度是(compact)紧凑,就是指所有iphone的横屏

自动布局
3.宽度是(Regular) 普通的,高度是(Compact)紧凑的,这是iphone plus的屏幕(5.5英寸屏幕)

自动布局
4. 宽度(Compact)紧凑,高度(Any)任意 是iphone 3.5,4,4.7的竖屏和横屏

自动布局
5.宽(any)任意,高(any)任意: 所有设备的屏幕

自动布局
6.宽度(regular)普通,高度(any)任意:所有ipad的横屏和竖屏

自动布局
7.宽(Compact)紧凑,高(Regular)普通: 所有iphone的竖屏

自动布局
8.宽(any)任意,高(Regular)普通:所有iphone的竖屏和所有ipad的横屏或竖屏

自动布局
9. 宽(Regular)普通,高(Regular)普通:所有ipad的横屏或竖屏

自动布局
》Autolayout在Storeboard布局QQ登陆界面,该登陆界面可以运行在所有的iphone和ipad上 1.Size Classes设置为any/any的
2.向storybaory中拖入一个UIImageView,作为头像
3.为头像添加约束
添加水平居中约束
自动布局
添加顶部与尺寸约束
自动布局
4.拖入一个TextField,添加约束
自动布局自动布局
5.使用相同方式添加和设置第二个文本框

》如何预览布局
1.打开预览界面

自动布局
2. 删除原有的预览
自动布局
3.添加预览图像
自动布局
当添加多个界面,在笔记本中可以通过两根手指来移动,查看所有界面的显示情况

4.查看横屏界面
自动布局
6.预览结果:无论在什么样的屏幕均可以正常展示

》如何单独设置横屏或竖排状态才显示某些控件
1.设置size classes 的状态为iphone的横屏
自动布局自动布局
2.拖入一个开关,设置它的autolayou约束

2.1设置与第二个文本框左对齐

自动布局
选择left表示左对齐

自动布局
设置与第二个文本框的距离

自动布局

3.在预览中查看:

iPhone的竖屏不会出现开关,iPhone的横屏下会出现开关
》如何禁用某种状态下的size class(show the Attribute -》install)
自动布局
2.添加size classes

自动布局
》如何利用Xcode6查看布局层级结构(类似Reveal) 为了能够看到图片,先给图片设置一个背景
自动布局
点击后出现,下图,可以通过鼠标旋转图形来查看图形的层次结构
自动布局

C02-Images.xcassets中Size Classes [了解]

1.images.xcassets在Xcode6中的变化

》可以添加非png图片

在xcode5中只能添加png图片,在xcode6中可以添加png和jpg的图片

》Appicon有了相应得变化

1.增加3x的图片
2.可以设置iOS7,iOS8,iphone,ipad的应用图片

自动布局
》可以设置图片在指定状态下显示 (和SizeClasses一样)

2.练习:实现让图片在横屏状态和竖屏状态显示不同的图像

1.创建项目, Images.xcassets 拖入两张图片, storybaord中拖入一个UIImage,设置image属性

2.为这个image添加 在父控件水平中心,距离父控件顶部20,宽高均为100的约束添加完毕后

自动布局
》在xcode6多了两个选项, width和height. 这两个选项和sizeclass中的是一样的
自动布局
》点击图片设置高度属性为Any&Compact(前一个*代表宽度, 后面一个代表高度),

*是任意的, +是正常的 -号是紧凑的

自动布局
往1x[* -] 的位置拖入一张图片

自动布局
运行:
自动布局自动布局


本博客内容既有转载自网络的内容,也有本作者原创内容,仅供学习与交流之用
如有侵权或者错误之处,请及时在下方留言!
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址