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

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

案例2

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

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

案例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;
}

在这儿我们是通过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;
}

这里,用到了一个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));
}

运行效果如下:

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;
}

随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];
}

关于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)]];

上面的例子实现了两个按钮的垂直排列。如果想要水平排列,修改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全解

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

  2. 一般将来时语法课教案_「英语语法」一般过去时用法技巧全解

    大家好,我是教课蚪英语的张老师,今天我们来学习英语语法100讲的第一课,一般过去时! 一.首先我们了解一下什么是一般过去时? 英语语法 1. 概念: 描述过去的状态或过去的动作. 在英语中,非现在的以 ...

  3. atca背板_ATCA介绍全解.ppt

    ATCA介绍全解 ATCA - 概述Advanced Telecommunications Computing Architecture 高性能计算机和网络通信设备的要求: 1) 足够强的数据处理能力 ...

  4. 生成对抗网络gan原理_中国首个“芯片大学”即将落地;生成对抗网络(GAN)的数学原理全解...

    开发者社区技术周刊又和大家见面了,萌妹子主播为您带来第三期"开发者技术联播".让我们一起听听,过去一周有哪些值得我们开发者关注的重要新闻吧. 中国首个芯片大学,南京集成电路大学即将 ...

  5. Java IO编程全解(五)——AIO编程

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7794151.html 前面讲到:Java IO编程全解(四)--NIO编程 NIO2.0引入了新的异步通道的 ...

  6. Sql Server函数全解三数据类型转换函数和文本图像函数

    原文:Sql Server函数全解<三>数据类型转换函数和文本图像函数 一:数据类型转换函数 在同时处理不同数据类型的值时,SQL Server一般会自动进行隐士类型转换.对于数据类型相近 ...

  7. html5相关介绍ppt,html5介绍全解.ppt

    html5介绍全解 渐变 (Gradients) 线性渐变: background: linear-gradient(to right, red, orange, yellow, green, blu ...

  8. 语义分割中的深度学习方法全解:从FCN、SegNet到各版本DeepLab

    语义分割中的深度学习方法全解:从FCN.SegNet到各版本DeepLab 原文:https://www.sohu.com/a/155907339_610300 图像语义分割就是机器自动从图像中分割出 ...

  9. 人工操作阶段计算机是如何工作的,第一章计算机基础概述全解.ppt

    第一章计算机基础概述全解 1.2.3 汉字编码 汉字的编码 国标码:中文内码之一,汉字信息交换的标准编码.国标码是不可能在计算机内部直接采用.于是, 汉字的机内码采用变形国标码 . 国标码:作为转换为 ...

最新文章

  1. Djkastra堆(手写堆)优化版
  2. 企业绩效管理推不动,如何用绩效创造价值?
  3. 深度学习的核心:掌握训练数据的方法
  4. java类与对象的最初理解
  5. 华为机试题【9】-整数分割为2的幂次
  6. [ECMAScript] 说说你对class的理解
  7. 指针右左法则----复杂指针解析
  8. 【读书笔记】并发编程需要注意的几个典型问题
  9. Java的数据库编程之背景概述
  10. 苏宁张近东:春节期间拿出3亿补贴一线员工
  11. linux主题管理器,XFCE 主题管理器:一款单一的GUI主题管理器,更改任何XFCE主题(带预览)...
  12. 夏至与北回归线的故事
  13. QQ农场外挂、QQ牧场外挂专偷QQ号
  14. html页面生成easyui,Easyui 为网页创建边框布局_EasyUI 教程
  15. 【Android 逆向】ART 脱壳 ( dex2oat 脱壳 | /art/dex2oat/dex2oat.cc#Dex2oat 函数源码 )
  16. Android入门篇
  17. 逻辑回归原理及推导过程
  18. 数据库设计中String类型的数据库类型选择
  19. 产学互为表里,携手方见大道:华为云AI院长峰会的价值思考
  20. iOS-画一个钉钉圆形带名字的头像

热门文章

  1. UA MATH571A R语言回归分析实践 多元回归1 医疗费用的决定
  2. Cesium在地球上添加一个3D立方体
  3. 词法分析器和lex工具基本学习
  4. 通过View.post()获取View的宽高
  5. UR #3 核聚变反应强度( gcd )
  6. 生产者消费者模式 php 【转】
  7. 《如何阅读一本书》之 阅读的层次
  8. 一个用于分页的page类
  9. 使用office生成PDF文件
  10. python中if brthon环境安装包_Ant、Gradle、Python三种打包方式的介绍