AutoLayout简介

Autolayout是一种全新的布局技术,专门用来布局UI界面的,用来取代Frame布局在遇见屏幕尺寸多重多样的问题。Autolayout自iOS 6开始引入,但是由于Xcode 4的不给力,当时并没有得到大规模推广。在iOS 7(Xcode5)开始,Autolayout的开发效率得到很大的提升,苹果官方也推荐开发者尽量使用Autolayout来布局UI界面,减少纯代码的方式。
那么AutoLayout怎么使用呢?

VFL

VFL(Virsual Format Language)是一种虚拟的格式化语言,主要用来创建AutoLayout的约束字符串。
示例,如:V: |-(0)-Label1-(0)-Label2-(0)-| 方向:从左到右,从上到下
V:表示方向为垂直方向,也就是竖向;H为横向。
|:竖线表示为边界(当前所在View的边界),这里紧邻方向表示符V,方向是从上到下,因此表示上面界。
0:NSNumber 0 表示约束值为0。这里是Label1距离上边界的约束为0。
Label1:表示对象Label1。
0:表示Label1和Label2的约束为0.
Label2:表示对象Label2。
0:表示Label2和下边界的约束为0.
|:表示下边界。

关于[VFL官网]详细知识,请查看官方的介绍

AutoLayout IB使用方式

为了让布局能够在不同屏幕的size上都能够表现正常,我们需要对其增加“约束”。然后,在不同屏幕尺寸下view就能够按照约束来局。

添加如下约束:

属性说明:
1:距离边缘 最上面的4个虚线表示某个View的距离上边 左边 右边 下边多高
2:那个蓝色的Constrain To Margins 是iPhone6出现之后。
Apple 觉得更大的分辨率有点间距好看, 默认为8 , 如果这个勾上了 这个View距离四周的值就变成了 你输入的值+8。 一般建议勾掉 。
  • 1
  • 2
  • 3
  • 4

案例1

设置某个View距离父View上下左右间距全部为20。

案例2

某个View距离父View的左侧20,上20,宽高均为100。

注意:我在添加约束的时候有个选项叫做updateFrame 如果勾选 会直接将Frame调整到真实值 ,而不需要再次update 。
  • 1

案例3

某个View距离在父View的左侧20 案例2中白色View 上20 宽高和Demo2中的宽高一样。

然后,点击某个约束。

对其处理

属性说明:

  • Leading Edges:左对齐
  • Trailing Edges:右对齐
  • Top Edges:上对齐
  • Bottom Edges:下对齐
  • Horizontal Centers:水平中心对齐
  • Vertical Centers:竖向中心对齐
  • Baselines:基线对齐
  • Horizontal Center in Container:对齐容器中的水平中心
  • Vertical Center in Container:对齐容器中的竖向中心

案例4

某个View距离在父View的右侧20 案例3中白色View上20 宽高和案例3中的宽高一样 并且对齐。

案例5

某个label和另外一个label基线对齐。

像label 默认是有宽度的 宽度就是字体自适应的。这样我们就可以不给UIlabel 高度 把Label的NumberOfline = 0就可以自适应高度了。

Tip

1,有时候约束太多的时候 我们可以给某个View起个假名字以起到唯一标识的作用。
2,View总是选不中怎么办?按 ctrl + shift + 单击。
3,当ScrollView过长无法编辑怎么办?将控制器改为Freedom 修改ContentView的高度约束 这样ScrollView 就可以滚动了。

UItableViewCell高度计算

为了方便说明,本部分知识主要从以下几个方面讲解。

  • AutoLayout with UILabel in UITableViewCell
  • AutoLayout with UITextView in UITableViewCell
  • Manual Layout with UILabel in UITableViewCell
  • Manual Layout with UITextView in UITableViewCell
  • 随UITextView高度动态改变Cell高度

AutoLayout with UILabel

创建一个空的xib,命名为C1.xib, 然后拖入一个UITableViewCell控件。接着创建一个UITableViewCell的子类,命名为C1类。然后在C1.xib中,将与C1类进行关联。只需要在Class那里写入关联的类名C1即可。

还有由于UITableViewCell需要重用功能,所以我们还需要设置一个重用标识。

下面是使用autoLayout的布局。

接着我们在UITableView中来使用我们自定义的UITableViewCell C1。首先我们创建一个UITableViewController的子类T1ViewController, 接着在Main.storyboard中拖入一个UITableViewController,并关联T1ViewController。

Auto Layout with UITextView

同样参考上面我们创建一个C2.xib, UITableViewCell的子类C2,并关联C2.xib与C2类。并在C2.xib中对其布局,同样使用了auto layout. 布局如下图:

创始UITableViewController的了类T2ViewController,在Main.storyboard中拖入UITableViewController,并关联他们。接着代码中注册C2.xib到UITableView。
如下面是计算UITableView高度的代码:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{C2 *cell = (C2 *)self.prototypeCell;cell.t.text = [self.tableData objectAtIndex:indexPath.row];CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];CGSize textViewSize = [cell.t sizeThatFits:CGSizeMake(cell.t.frame.size.width, FLT_MAX)];CGFloat h = size.height + textViewSize.height;h = h > 89 ? h : 89;  //89是图片显示的最低高度, 见xibNSLog(@"h=%f", h);return 1 + h;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这儿我们是通过sizeThatFits:计算的UITextView的高度,然后加上systemLayoutSizeFittingSize:返回的高度。为什么要这样呢? 因为UITextView内容的高度不会影响systemLayoutSizeFittingSize计算。
下面是UITextView的实例:

此图中距顶的约束是10, 距底的约束8, 距左边约束是87,距右边的约束是13, 那么systemLayoutSizeFittingSize:返回的CGSize为height等于19, size等于100. 它UITextView的frame是不影响systemLayoutSizeFittingSize:的计算。所以,我们需要加上textViewSize.height。

Manual Layout with UILabel

按照前面介绍的,我们需要创建C3.xib, C3类, T3ViewController类,Main.storyboard中拖入UITableViewController,并分别建立关联。 为了简单,C3.xib中我就不加padding之类的了,如图:

然后添加如下的计算代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{C3 *cell = [self.tableView dequeueReusableCellWithIdentifier:@"C3"];cell.t.text = [self.tableData objectAtIndex:indexPath.row];[cell.t sizeToFit];return cell;
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {C3 *cell = (C3 *)self.prototypeCell;NSString *str = [self.tableData objectAtIndex:indexPath.row];cell.t.text = str;CGSize s = [str calculateSize:CGSizeMake(cell.t.frame.size.width, FLT_MAX) font:cell.t.font];CGFloat defaultHeight = cell.contentView.frame.size.height;CGFloat height = s.height > defaultHeight ? s.height : defaultHeight;NSLog(@"h=%f", height);return 1  + height;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

这里,用到了一个NSString的Cagetory方法,代码如下:

- (CGSize)calculateSize:(CGSize)size font:(UIFont *)font
{CGSize expectedLabelSize = CGSizeZero;if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle.copy};expectedLabelSize = [self boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;}else {expectedLabelSize = [self sizeWithFont:fontconstrainedToSize:sizelineBreakMode:NSLineBreakByWordWrapping];}return CGSizeMake(ceil(expectedLabelSize.width), ceil(expectedLabelSize.height));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

运行效果如下:

Manual Layout with UITextView

按照前面介绍的,我们需要创建C4.xib, C4类, T4ViewController类,Main.storyboard中拖入UITableViewController,并分别建立关联。 为了简单,C4.xib中我就不加padding之类的了,如图:

相关代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{C4 *cell = [self.tableView dequeueReusableCellWithIdentifier:@"C4"];cell.t.text = [self.tableData objectAtIndex:indexPath.row];[cell.t sizeToFit];return cell;
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {C4 *cell = (C4 *)self.prototypeCell;NSString *str = [self.tableData objectAtIndex:indexPath.row];cell.t.text = str;CGSize s =  [cell.t sizeThatFits:CGSizeMake(cell.t.frame.size.width, FLT_MAX)];CGFloat defaultHeight = cell.contentView.frame.size.height;CGFloat height = s.height > defaultHeight ? s.height : defaultHeight;return 1  + height;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

随UITextView高度改变Cell高度

当UITextView内容改变的时候,计算自身高度,然后通知UITableView更新,这样就会触发UITableViewCell高度重新计算,从而改变Cell的高度。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{C5 *cell = [self.tableView dequeueReusableCellWithIdentifier:@"C5"];cell.t.text = @"123";cell.t.delegate = self;return cell;
}#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {C5 *cell = (C5 *)self.prototypeCell;cell.t.text = self.updatedStr;CGSize s =  [cell.t sizeThatFits:CGSizeMake(cell.t.frame.size.width, FLT_MAX)];CGFloat defaultHeight = cell.contentView.frame.size.height;CGFloat height = s.height > defaultHeight ? s.height : defaultHeight;return 1  + height;
}#pragma mark - UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {if ([text isEqualToString:@"\n"]) {NSLog(@"h=%f", textView.contentSize.height);}return YES;
}- (void)textViewDidChange:(UITextView *)textView {self.updatedStr = textView.text;[self.tableView beginUpdates];[self.tableView endUpdates];
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

关于UITableViewCell使用自动布局的优化可以查看下面的介绍:
优化UITableViewCell高度计算。

StackView

UIStackView是iOS9新引入的控件,它支持垂直和水平排列多个子视图(SubView)。例如:水平放置三个按钮,等宽,并且按钮间的间隙为10,如果自己实现会比较麻烦,而使用UIStackView则很容易实现。UIStackView目前只支持iOS9+版本,如果要在iOS 7版本上使用UIStackView,可以使用下面两个第三方库:OAStackView和TZStackView。其中:

  • OAStackView,基于OC的StackView库,支持iOS7+以上的系统,同时支持代码和IB视图。
  • TZStackView,基于Swift的StackView库,同样支持iOS7+以上的系统,但是不支持storyboard。

OAStackView实现子视图等分

案例1

例如,下面的例子是使用OAStackView实现视图等分的例子。

相关代码如下:

 UILabel *l1 = [[UILabel alloc] init];l1.text = @"Label 1";UILabel *l2 = [[UILabel alloc] init];l2.text = @"Label 2";OAStackView *stackView = [[OAStackView alloc] initWithArrangedSubviews:@[l1, l2]];stackView.translatesAutoresizingMaskIntoConstraints = NO;[self.view addSubview:stackView];[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[stackView]"options:0metrics:0views:NSDictionaryOfVariableBindings(stackView)]];[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[stackView]"options:0metrics:0views:NSDictionaryOfVariableBindings(stackView)]];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

上面的例子实现了两个按钮的垂直排列。如果想要水平排列,修改stackView.axis值为UILayoutConstraintAxisHorizontal即可。需要注意,因为不是用IB创建的View,所以要设定View的translatesAutoresizingMaskIntoConstraints属性为NO,否则排列属性不生效。当非IB创建时,属性默认为YES;当IB创建View时,属性默认为NO。

案例2

在水平方向上放4张图片,图片等分。
1,首先在页面上拖拽1个imageView,将它的宽高都设置成50。

2,然后再添加三个imageView,将界面上的四个ImageView设置等宽等高。

3,然后再将他们加入到Stack View中,设置Stack View 的distribution属性为 Equal Spacing(等间距)。

4,最后,设置Stack View 的位置

StackView属性

在理解StackView时,有几个属性需要理解:
Axis: 这个属性是改变UIStackView中的排布方式的属性,其中有水平排布与垂直排布

  • Alignment:这个属性是其中子视图的位置摆布方式默认是填充摆布

  • Fill:子视图填充他所在的位置(默认)

  • Leading:子视图头部对齐

  • Center:子视图居中对齐

  • Trailing:子视图尾部对齐

  • Distribution:子视图的大小

  • Fill:子视图填充整个UIStackView

  • Fill Equally:子视图填充空白区域并等分

  • Fill Proportionally:按照目前相对位置进行填充

  • Equal Spacing:等间距

  • Spacing设置子视图之间的间距大小

  • Baseline Relative:如果设置子视图间距的大小为基线到下一个视图的头部

AutoLayout 讲解相关推荐

  1. autolayout autoresizing

    WWDC 2012 Session笔记--202, 228, 232 AutoLayout(自动布局)入门 这是博主的WWDC2012笔记系列中的一篇,完整的笔记列表可以参看这里.如果您是首次来到本站 ...

  2. AutoLayout全解

    AutoLayout简介 Autolayout是一种全新的布局技术,专门用来布局UI界面的,用来取代Frame布局在遇见屏幕尺寸多重多样的问题.Autolayout自iOS 6开始引入,但是由于Xco ...

  3. AutoLayout代码布局使用大全—一种全新的布局思想

    相信ios8出来之后,不少的ios程序员为了屏幕的适配而烦恼.相信不少的人都知道有AutoLayout 这么个玩意可以做屏幕适配,事实上,AutoLayout不仅仅只是一个为了多屏幕适配的工具, 它真 ...

  4. AutoLayout(自动布局)详细教程

    转载  http://www.onevcat.com/2012/09/autoayout/ WWDC 2012 Session笔记--202, 228, 232 AutoLayout(自动布局)入门 ...

  5. 史上比较用心的纯代码实现 AutoLayout

    入职有两三个月了吧,都是使用 Objective-C 纯代码(虽然有时候偷偷参杂一些 Swift 开源库)来编写公司APP,写布局的时候几乎都是要么在初始化的时候用 initWithFrame,要么就 ...

  6. 在Scrollview中使用AutoLayout

    AutoLayout 与 UIScrollView的相遇是一个不可避免的场景,像UITableView.UIWebView这些都是继承于UIScrollView的,关于它们的autolayout布局大 ...

  7. 寒哥细谈之AutoLayout全解

    看到群中好多朋友还停留在Frame布局的痛苦时代,以及有些开发者接手别人的就项目发现布局一团乱. 而且没有启动图的时候并不是真正真正适配iPhone 6(S).iPhone6(S) Plus等设备 . ...

  8. iOS - AutoLayout

    前言 NS_CLASS_AVAILABLE_IOS(6_0) @interface NSLayoutConstraint : NSObject@available(iOS 6.0, *) public ...

  9. Autolayout屏幕适配——代码实现(苹果公司 / VFL语言 / 第三方框架Masonry)

    在讲解如何通过代码来实现屏幕适配前,先来了解一下,屏幕适配中用到的约束添加的规则. 在创建约束之后,需要将其添加到作用的view上 在添加时要注意目标view需要遵循以下规则: 1. 约束规则 1&g ...

  10. Autolayout第三方库Masonry的入门与实践

    在如今的iOS开发中,Autolayout已经是不得不使用了,而且是我们主动的去拥抱Autolayout.使用Autolayout最普遍的方式就是在xib或者storyboard中可视化的添加各种约束 ...

最新文章

  1. 真「祖传代码」!你的 GitHub 代码已打包运往北极,传给 1000 年后人类
  2. windows 64位 dll文件 位置及python包rtree shapely安装
  3. python画图y轴在右侧_解决python中画图时x,y轴名称出现中文乱码的问题
  4. 如何评价模型的好坏(一)
  5. 监控聚币网行情 并实时发送到微信
  6. Redis分布式锁原理解析
  7. SQLServer 事物与索引
  8. linux系统系统安装,深度linux操作系统安装图文教程
  9. mysql外文文献中英文3千字_MySQL数据库管理外文中英文翻译文献.doc
  10. Samsung 6818平台首次编译遇到的问题
  11. python计算卡方值代码,python 基于卡方值分箱算法的实现示例
  12. 叠氮-二乙二醇-羟基Azido-PEG2-alcohol139115-90-5
  13. 计算机组成原理——指令系统(课程笔记)
  14. unity中AO、metallic、roughness贴图的使用方式
  15. 3级流水线11位-4位CRC循环冗余校验码生成器Verilog
  16. 如何清空python的IDLE?
  17. 在线作图|如何在线画一张精美的和弦图
  18. 微信小程序的校园二手物品交易平台系统 uniapp 小程序
  19. 用ExcelVBA下载股票板块历史数据
  20. 怎么才能在Mac电脑提醒事项添加提醒事项

热门文章

  1. win10应用商店无法安装
  2. 解析音视频网络传输技术之一
  3. win7创建桌面计算机,win7系统添加或删除虚拟桌面的方法介绍
  4. 接口大师(PhalApi专业版)项目实战经验分享,快速开发项目的新方式
  5. IGS精密星历及其下载(自PureSky_Memory的博客)
  6. 2021 年百度之星·程序设计大赛 - 初赛三
  7. Spring Boot + OAuth2 统一认证SSO单点登录
  8. 【数据挖掘】 基于二手车交易价格预测-数据分析
  9. HTML5CSS3网页设计仿微信通讯录页
  10. 如何用JavaScript实现轮播图(幻灯片)的制作