一、概要
通过对iOS8界面布局的学习和总结,发现autolayout才是主角,autolayout是iOS6引入的新特性,当时还粗浅的学习了下,可是没有真正应用到项目中。随着iOS设备尺寸逐渐碎片化,纯粹的hard code方式UI布局将会走向死角,而autoresizing方式也有其局限性,所以无论如何autolayout都将成为UI布局的重要方式。
前两篇以发烧友心态对iOS8界面布局的主要元素size class和autolayout进行了探索,发现要完全掌握autolayout需要大量的时间去实践总结。所以深入思考autolayout是很有必要的。你可能有和我同样的疑问,如下:
1、以后一律使用autolayout吗?除了在storyboard中使用autolayout,代码方式autolayout如何使用?
2、好像忽略了一个重要问题,就是view动画在autolayout如何实现?
3、autolayout有没有局限性和解决不了的问题?兼容性怎么样?效率怎么样?
4、……
二、研究开始
1、直接说以后都应该使用storyboard+autolayout感觉是不负责的说法,读了好多网络的帖子,最后总结如下情况使用autolayout会有帮助:
a 当需要展示的内容很多并且尺寸不固定;
b 程序需支持屏幕旋转(主要是iPad程序,iPhone程序横屏的场景有点非主流);
c 程序通用于iPhone和iPad;但storyboard中使用autolayout有利有弊,好处当然是可视化,实现简单功能很节省时间,但也有弊端,例如不小心移动一个控件就会让弄乱那些约束。抛开storyboard而使用autolayout,就需要代码定义约束了,而且代码量也不是很大。当app中一些view的出现时根据网络数据来决定的时候,代码方式可能更合适。
先看一个简单的Demo:
例子1:新建一个Single View Application template项目Demo4,在rootView上添加一个绿颜色的view,使新添加的view四个边距离superView四边20点宽
效果如图:使用storyboard来实现这个效果很简单,选中绿色view,然后添加4个相对于superview的边界约束,约束的数值设置为20,然后Update Frame就可以了,因为不区分iOS设备,所以size class可以设置为默认的wAny hAny。Demo下载
接下来使用代码来实现UI布局,目前有3种方法可以使用:(1)最基本的约束实现方式;(2)特殊格式化语言的约束实现方式;(3)第三方UIView-AutoLayout
(1)最基本的约束实现方式
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (void)viewDidLoad {  [super viewDidLoad];  // Do any additional setup after loading the view, typically from a nib.  self.view.translatesAutoresizingMaskIntoConstraints =NO;  UIView *newView = [UIView new];  newView.backgroundColor = [UIColor greenColor];  [self.view addSubview:newView];  newView.translatesAutoresizingMaskIntoConstraints =NO;  NSLayoutConstraint *constraint = nil;  constraint = [NSLayoutConstraint constraintWithItem:newView  attribute:NSLayoutAttributeLeading  relatedBy:NSLayoutRelationEqual  toItem:self.view  attribute:NSLayoutAttributeLeading  multiplier:1.0f  constant:20];  [self.view addConstraint:constraint];  constraint = [NSLayoutConstraint constraintWithItem:newView  attribute:NSLayoutAttributeTrailing  relatedBy:NSLayoutRelationEqual  toItem:self.view  attribute:NSLayoutAttributeTrailing  multiplier:1.0f  constant:-20];  [self.view addConstraint:constraint];  constraint = [NSLayoutConstraint constraintWithItem:newView  attribute:NSLayoutAttributeTop  relatedBy:NSLayoutRelationEqual  toItem:self.view  attribute:NSLayoutAttributeTop  multiplier:1.0f  constant:20];  [self.view addConstraint:constraint];  constraint = [NSLayoutConstraint constraintWithItem:newView  attribute:NSLayoutAttributeBottom  relatedBy:NSLayoutRelationEqual  toItem:self.view  attribute:NSLayoutAttributeBottom  multiplier:1.0f  constant:-20];  [self.view addConstraint:constraint];  }</span>  (2)特殊格式化语言的约束实现方式
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (void)viewDidLoad {  [super viewDidLoad];  self.view.translatesAutoresizingMaskIntoConstraints =NO;  UIView *newView = [UIView new];  newView.backgroundColor = [UIColor greenColor];  [self.view addSubview:newView];  newView.translatesAutoresizingMaskIntoConstraints =NO;  NSMutableArray *constraintArray = [NSMutableArray array];  [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[newView]-20-|"  options:0  metrics:nil  views:NSDictionaryOfVariableBindings(newView, self.view)]];  [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[newView]-20-|"  options:0  metrics:nil  views:NSDictionaryOfVariableBindings(newView, self.view)]];  [self.view addConstraints:constraintArray];
}</span>  (3)第三方UIView-AutoLayout
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (void)viewDidLoad {  [super viewDidLoad];  self.view.translatesAutoresizingMaskIntoConstraints =NO;  UIView *newView = [UIView new];  newView.backgroundColor = [UIColor greenColor];  [self.view addSubview:newView];  newView.translatesAutoresizingMaskIntoConstraints =NO;  [newView autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:20.0f];  [newView autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:20.0f];  [newView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:20.0f];  [newView autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:20.0f];
}</span>  以上3种方式都实现了我们想要的效果,看来代码实现autolayout也不是那么复杂!例子2:通过上边例子我们实现一个简单的UI布局,下面来一个稍微复杂点的,把上一篇中提到3个view布局的那个例子用代码布局实现一下,但难度有所增加,当size class切换的时候,页面布局发生相应的改变,效果如图:首先初始化3个View:
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (UIView *) alView {  UIView *newView = [UIView new];  newView.translatesAutoresizingMaskIntoConstraints =NO;  return newView;
}
UIView *greenView = [self alView];
greenView.backgroundColor = [UIColor greenColor];
[self.view addSubview:greenView];
UIView *yellowView = [self alView];
yellowView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:yellowView];
UIView *blueView = [self alView];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];</span>  接下来适配竖屏的约束:
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (NSMutableArray *) portraitConstraints:(UIView *)greenView :(UIView *)yellowView :(UIView *)blueView
{  NSMutableArray *constraintArray = [NSMutableArray array];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"H:|-20-[greenView]-20-[yellowView(==greenView)]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(greenView, yellowView)]];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"V:|-20-[greenView]-20-[blueView(==greenView)]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(greenView, blueView)]];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"V:|-20-[yellowView]-20-[blueView(==yellowView)]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(yellowView, blueView)]];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(blueView)]];  return constraintArray;
}</span>  然后横屏的约束:
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (NSMutableArray *) landscapeConstraints:(UIView *)greenView :(UIView *)yellowView :(UIView *)blueView
{  NSMutableArray *constraintArray = [NSMutableArray array];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"H:|-20-[greenView]-20-[yellowView(==greenView)]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(greenView, yellowView)]];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"V:|-20-[blueView]-20-[greenView(==blueView)]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(greenView, blueView)]];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"V:|-20-[blueView]-20-[yellowView(==blueView)]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(yellowView, blueView)]];  [constraintArray addObjectsFromArray:[NSLayoutConstraint  constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:0 metrics:nil  views:NSDictionaryOfVariableBindings(blueView)]];  return constraintArray;
}</span>  最后还要处理屏幕旋转:
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection  withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
{  [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];  [coordinator animateAlongsideTransition:^(id <UIViewControllerTransitionCoordinatorContext> context) {  if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {  NSLog(@"%s----%d", __FUNCTION__, __LINE__);  [self.view removeConstraints:self.view.constraints];  [self.view addConstraints:[self landscapeConstraints:self.greenView_ :self.yellowView_ :self.blueView_]];  } else {  NSLog(@"%s----%d", __FUNCTION__, __LINE__);  [self.view removeConstraints:self.view.constraints];  [self.view addConstraints:[self portraitConstraints:self.greenView_ :self.yellowView_ :self.blueView_]];  }  [self.view setNeedsLayout];  } completion:nil];
}</span>  这样就实现了我们预期的效果,总结下来,auotlayout就是给view添加足够的约束,让view系统可以根据约束来计算出一个view的frame。动手练习一下吧!2、view动画在autolayout实现
当布局发生改变时,相当于对子view进行重新布局,而子view重新布局调用 layoutIfNeeded,所以动画可以这样实现:
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">- (void)animateConstraints
{  [UIView animateWithDuration:0.5 animations:^{  [self.view layoutIfNeeded];  }];
}</span>  Github上已经有Demo了!3、autolayout有没有局限性和解决不了的问题?兼容性怎么样?效率怎么样?
autolayout对view transforms支持的不好,这里有帖子详细描述了这个问题。
至于兼容性,只从iOS6就已经提出了autolayout的概念,现在iOS5系统不是很多了,甚至iOS6系统都已经升级为iOS7,未来一段时间大部分用户应该是使用iOS7和iOS8系统,所以兼容性问题不会太大,但size class是iOS8才有的概念,所以还有有一定的适配工作量。
效率话题这里有提到,有时间再细研究。结束语:时间和体力总是有限的,标题是autolayout详解,可想达到详解还需要更多的时间去实践和总结,还有一些细节没有体现出来:
例如:
[objc] view plaincopy在CODE上查看代码片派生到我的代码片
<span style="font-size:12px;">[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[newView]-20-|"options:0 metrics:nil views:NSDictionaryOfVariableBindings(newView, self.view)]</span>
1、这其中各个参数的含义,另外约束还有个优先级的概念
2、@"H:|-20-[newView]-20-|" 这种可视化布局字符串的含义等等,有空再补充了!
本篇内容所有Demo
欢迎指出错误,不胜感激。

iOS8.0新特性 autoLayout应用相关推荐

  1. JDK5.0新特性系列---目录

    JDK5.0新特性系列---目录 JDK5.0新特性系列---1.自动装箱和拆箱 JDK5.0新特性系列---2.新的for循环 JDK5.0新特性系列---3.枚举类型 JDK5.0新特性系列--- ...

  2. [转]C# 2.0新特性与C# 3.5新特性

    C# 2.0新特性与C# 3.5新特性 一.C# 2.0 新特性: 1.泛型List<MyObject> obj_list=new List(); obj_list.Add(new MyO ...

  3. Servlet 3.0 新特性概述

    Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若 ...

  4. Redis 6.0 新特性-多线程连环13问!

    来自:码大叔 导读:支持多线程的Redis6.0版本于2020-05-02终于发布了,为什么Redis忽然要支持多线程?如何开启多线程?开启后性能提升效果如何?线程数量该如何设置?开启多线程后会不会有 ...

  5. WCF4.0新特性体验(3):标准终结点(Standard Endpoints)

    今天在WCF4.0新特性体验第3节,我们介绍WCF4.0里的标准终结点概念,也就是Standard Endpoints. WCF4.0提供了那些标准终结点?他们有什么作用?如何使用标准终结点?如何该表 ...

  6. Servlet 2.0 Servlet 3.0 新特性

    概念:透传. Callback 在异步线程中是如何使用的.?? Servlet 2.0 && Servlet 3.0 新特性 Servlet 2.0 && Servle ...

  7. C#6.0,C#7.0新特性

    C#6.0,C#7.0新特性 C#6.0新特性 Auto-Property enhancements(自动属性增强) Read-only auto-properties (真正的只读属性) Auto- ...

  8. WCF4.0新特性体验(6):路由服务Routing Service(下)

    紧接前文WCF4.0新特性体验(5):路由服务Routing Service(上).今天我们介绍WCF4.0消息路由的实现机制,然后会讲解路由服务的实现过程. [4]WCF与路由服务: 其实在介绍WC ...

  9. 【收藏】C# 2.03.0新特性总结

    c#2.0新特性 范型 我们知道通用的数据结构可以采用object存储任何数据类型.使用object问题是: 显示的强制转带来的代码复杂性 换装箱拆箱的性能损失(为什么有性能损失?因为涉及动态内存分配 ...

最新文章

  1. 阿里云 刷新缓存 java_【从入门到放弃-Java】并发编程-NIO-Buffer
  2. Who is the best at Dataset X?
  3. 罗永浩、戴威的 C 位消亡史
  4. 【转载】Android编译系统Makefile(Android.mk)写法
  5. C++ 对象模型学习记录(3)--- 第1章 关于对象(未完)
  6. 需求变更,产品经理的良心也会痛!
  7. MYSQL连接出现Auth_连接MySQL数据库出现时Authentication plugin 'caching_sha2_password' cannot be loaded的解决办法...
  8. Tomcat原理系列之一:整体架构,抓住主线
  9. java实现五子棋_Java的五子棋实现
  10. 水面反光如何拍摄_反光倒影的摄影怎么拍?
  11. 服务器应该选哪家好?
  12. 移动端UML图应用之UML结构图——包图、部署图和组件图
  13. 老A:什么是抖音弹幕互动游戏,玩法以及如何参与
  14. Day 3 (云计算-zsn)
  15. vue-music 跨域获取QQ音乐歌单接口
  16. eclipse出现编译错误:resolution will not be reattempted until the update interval o f central has elapsed
  17. AEJoy —— 表达式之闪烁光标的打字机效果(二)【JS】
  18. Java知识之Git
  19. 使用Kong和Konga管理微服务和API
  20. 联合作战态势可视化决策系统

热门文章

  1. Type-C是如何实现无方向正反接的?
  2. vue模仿新年集福活动(移动端)
  3. 中英文切换(servlet)
  4. 一生受用的三张PPT
  5. 用java产生一个范围在1到1000之间的随机数
  6. C语言系列(二)有符号数和无符号数详解
  7. ZYNQ之FPGA学习----Vivado功能仿真
  8. JDO 的架构作一个简单的介绍
  9. 生活记录-- 林微因《分手信》
  10. Python之HTML解析方法