一、概要

通过对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 plain copy
  1. <span style="font-size:12px;">- (void)viewDidLoad {
  2. [super viewDidLoad];
  3. // Do any additional setup after loading the view, typically from a nib.
  4. self.view.translatesAutoresizingMaskIntoConstraints =NO;
  5. UIView *newView = [UIView new];
  6. newView.backgroundColor = [UIColor greenColor];
  7. [self.view addSubview:newView];
  8. newView.translatesAutoresizingMaskIntoConstraints =NO;
  9. NSLayoutConstraint *constraint = nil;
  10. constraint = [NSLayoutConstraint constraintWithItem:newView
  11. attribute:NSLayoutAttributeLeading
  12. relatedBy:NSLayoutRelationEqual
  13. toItem:self.view
  14. attribute:NSLayoutAttributeLeading
  15. multiplier:1.0f
  16. constant:20];
  17. [self.view addConstraint:constraint];
  18. constraint = [NSLayoutConstraint constraintWithItem:newView
  19. attribute:NSLayoutAttributeTrailing
  20. relatedBy:NSLayoutRelationEqual
  21. toItem:self.view
  22. attribute:NSLayoutAttributeTrailing
  23. multiplier:1.0f
  24. constant:-20];
  25. [self.view addConstraint:constraint];
  26. constraint = [NSLayoutConstraint constraintWithItem:newView
  27. attribute:NSLayoutAttributeTop
  28. relatedBy:NSLayoutRelationEqual
  29. toItem:self.view
  30. attribute:NSLayoutAttributeTop
  31. multiplier:1.0f
  32. constant:20];
  33. [self.view addConstraint:constraint];
  34. constraint = [NSLayoutConstraint constraintWithItem:newView
  35. attribute:NSLayoutAttributeBottom
  36. relatedBy:NSLayoutRelationEqual
  37. toItem:self.view
  38. attribute:NSLayoutAttributeBottom
  39. multiplier:1.0f
  40. constant:-20];
  41. [self.view addConstraint:constraint];
  42. }</span>

(2)特殊格式化语言的约束实现方式

[objc]  view plain copy
  1. <span style="font-size:12px;">- (void)viewDidLoad {
  2. [super viewDidLoad];
  3. self.view.translatesAutoresizingMaskIntoConstraints =NO;
  4. UIView *newView = [UIView new];
  5. newView.backgroundColor = [UIColor greenColor];
  6. [self.view addSubview:newView];
  7. newView.translatesAutoresizingMaskIntoConstraints =NO;
  8. NSMutableArray *constraintArray = [NSMutableArray array];
  9. [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[newView]-20-|"
  10. options:0
  11. metrics:nil
  12. views:NSDictionaryOfVariableBindings(newView, self.view)]];
  13. [constraintArray addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[newView]-20-|"
  14. options:0
  15. metrics:nil
  16. views:NSDictionaryOfVariableBindings(newView, self.view)]];
  17. [self.view addConstraints:constraintArray];
  18. }</span>

(3)第三方UIView-AutoLayout

[objc]  view plain copy
  1. <span style="font-size:12px;">- (void)viewDidLoad {
  2. [super viewDidLoad];
  3. self.view.translatesAutoresizingMaskIntoConstraints =NO;
  4. UIView *newView = [UIView new];
  5. newView.backgroundColor = [UIColor greenColor];
  6. [self.view addSubview:newView];
  7. newView.translatesAutoresizingMaskIntoConstraints =NO;
  8. [newView autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:20.0f];
  9. [newView autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:20.0f];
  10. [newView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:20.0f];
  11. [newView autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:20.0f];
  12. }</span>

以上3种方式都实现了我们想要的效果,看来代码实现autolayout也不是那么复杂!

例子2:通过上边例子我们实现一个简单的UI布局,下面来一个稍微复杂点的,把上一篇中提到3个view布局的那个例子用代码布局实现一下,但难度有所增加,当size class切换的时候,页面布局发生相应的改变,效果如图:

            

首先初始化3个View:

[objc]  view plain copy
  1. <span style="font-size:12px;">- (UIView *) alView {
  2. UIView *newView = [UIView new];
  3. newView.translatesAutoresizingMaskIntoConstraints =NO;
  4. return newView;
  5. }
  6. UIView *greenView = [self alView];
  7. greenView.backgroundColor = [UIColor greenColor];
  8. [self.view addSubview:greenView];
  9. UIView *yellowView = [self alView];
  10. yellowView.backgroundColor = [UIColor yellowColor];
  11. [self.view addSubview:yellowView];
  12. UIView *blueView = [self alView];
  13. blueView.backgroundColor = [UIColor blueColor];
  14. [self.view addSubview:blueView];</span>

接下来适配竖屏的约束:

[objc]  view plain copy
  1. <span style="font-size:12px;">- (NSMutableArray *) portraitConstraints:(UIView *)greenView :(UIView *)yellowView :(UIView *)blueView
  2. {
  3. NSMutableArray *constraintArray = [NSMutableArray array];
  4. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  5. constraintsWithVisualFormat:@"H:|-20-[greenView]-20-[yellowView(==greenView)]-20-|" options:0 metrics:nil
  6. views:NSDictionaryOfVariableBindings(greenView, yellowView)]];
  7. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  8. constraintsWithVisualFormat:@"V:|-20-[greenView]-20-[blueView(==greenView)]-20-|" options:0 metrics:nil
  9. views:NSDictionaryOfVariableBindings(greenView, blueView)]];
  10. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  11. constraintsWithVisualFormat:@"V:|-20-[yellowView]-20-[blueView(==yellowView)]-20-|" options:0 metrics:nil
  12. views:NSDictionaryOfVariableBindings(yellowView, blueView)]];
  13. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  14. constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:0 metrics:nil
  15. views:NSDictionaryOfVariableBindings(blueView)]];
  16. return constraintArray;
  17. }</span>

然后横屏的约束:

[objc]  view plain copy
  1. <span style="font-size:12px;">- (NSMutableArray *) landscapeConstraints:(UIView *)greenView :(UIView *)yellowView :(UIView *)blueView
  2. {
  3. NSMutableArray *constraintArray = [NSMutableArray array];
  4. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  5. constraintsWithVisualFormat:@"H:|-20-[greenView]-20-[yellowView(==greenView)]-20-|" options:0 metrics:nil
  6. views:NSDictionaryOfVariableBindings(greenView, yellowView)]];
  7. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  8. constraintsWithVisualFormat:@"V:|-20-[blueView]-20-[greenView(==blueView)]-20-|" options:0 metrics:nil
  9. views:NSDictionaryOfVariableBindings(greenView, blueView)]];
  10. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  11. constraintsWithVisualFormat:@"V:|-20-[blueView]-20-[yellowView(==blueView)]-20-|" options:0 metrics:nil
  12. views:NSDictionaryOfVariableBindings(yellowView, blueView)]];
  13. [constraintArray addObjectsFromArray:[NSLayoutConstraint
  14. constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:0 metrics:nil
  15. views:NSDictionaryOfVariableBindings(blueView)]];
  16. return constraintArray;
  17. }</span>

最后还要处理屏幕旋转:

[objc]  view plain copy
  1. <span style="font-size:12px;">- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection
  2. withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator
  3. {
  4. [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator];
  5. [coordinator animateAlongsideTransition:^(id <UIViewControllerTransitionCoordinatorContext> context) {
  6. if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
  7. NSLog(@"%s----%d", __FUNCTION__, __LINE__);
  8. [self.view removeConstraints:self.view.constraints];
  9. [self.view addConstraints:[self landscapeConstraints:self.greenView_ :self.yellowView_ :self.blueView_]];
  10. } else {
  11. NSLog(@"%s----%d", __FUNCTION__, __LINE__);
  12. [self.view removeConstraints:self.view.constraints];
  13. [self.view addConstraints:[self portraitConstraints:self.greenView_ :self.yellowView_ :self.blueView_]];
  14. }
  15. [self.view setNeedsLayout];
  16. } completion:nil];
  17. }</span>

这样就实现了我们预期的效果,总结下来,auotlayout就是给view添加足够的约束,让view系统可以根据约束来计算出一个view的frame。动手练习一下吧!

2、view动画在autolayout实现

当布局发生改变时,相当于对子view进行重新布局,而子view重新布局调用 layoutIfNeeded,所以动画可以这样实现:

[objc]  view plain copy
  1. <span style="font-size:12px;">- (void)animateConstraints
  2. {
  3. [UIView animateWithDuration:0.5 animations:^{
  4. [self.view layoutIfNeeded];
  5. }];
  6. }</span>

Github上已经有Demo了!

3、autolayout有没有局限性和解决不了的问题?兼容性怎么样?效率怎么样?

autolayout对view transforms支持的不好,这里有帖子详细描述了这个问题。

至于兼容性,只从iOS6就已经提出了autolayout的概念,现在iOS5系统不是很多了,甚至iOS6系统都已经升级为iOS7,未来一段时间大部分用户应该是使用iOS7和iOS8系统,所以兼容性问题不会太大,但size class是iOS8才有的概念,所以还有有一定的适配工作量。

效率话题这里有提到,有时间再细研究。

结束语:时间和体力总是有限的,标题是autolayout详解,可想达到详解还需要更多的时间去实践和总结,还有一些细节没有体现出来:

例如:

[objc]  view plain copy
  1. <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

本篇中的橙色字体都是资源哦,,可点击继续学习深层次的哈!

iOS 8 AutoLayout 及SizeClass(三) 使用详解 好多值得学习及研究的地方相关推荐

  1. Pinterest 3.0 for iOS设计过程——升级iOS7设计思路详解

    Pinterest 3.0 for iOS设计过程--升级iOS7设计思路详解 时间2013-12-11 11:39:31  苹果开发中文站 原文  http://www.cocoachina.com ...

  2. iOS 内购(In-App Purchase)详解

    iOS 内购(In-App Purchase)详解 概述 IAP 全称:In-App Purchase,是指苹果 App Store 的应用内购买,是苹果为 App 内购买虚拟商品或服务提供的一套交易 ...

  3. iOS 7: iPhone/iPad应用开发技术详解

    iOS 7: iPhone/iPad应用开发技术详解 作者:刘一道 出版社:机械工业出版社 出版年:2013-11 页数:507 定价:79.00元 ISBN:9787111440512 样章下载:h ...

  4. iOS 7 iPhone iPad应用开发技术详解

    2019独角兽企业重金招聘Python工程师标准>>> iOS 7 iPhone iPad应用开发技术详解 本书内容全面,从 Objective-C语法知识.iOS功能特 性,到高级 ...

  5. C++11 并发指南三(Lock 详解)(转载)

    multithreading 多线程 C++11 C++11多线程基本使用 C++11 并发指南三(Lock 详解) 在 <C++11 并发指南三(std::mutex 详解)>一文中我们 ...

  6. mac linux win三系统安装教程,macbookpro上安装三系统详解教程(macosxwindowslinuxubuntu).doc...

    macbookpro上安装三系统详解教程(macosxwindowslinuxubuntu) macbook pro上安装三系统详解教程(mac os x+windows+linux ubuntu) ...

  7. 数据库三范式详解,优缺点,解决了什么问题?

    https://zhuanlan.zhihu.com/p/20028672 三范式详解 解决了什么问题:(上面也有讲到)https://blog.csdn.net/qq_41174684/articl ...

  8. iOS开发支付篇——内购(IAP)详解

    iOS开发支付篇--内购(IAP)详解 苹果客户端购买虚拟商品是需要走内购 先看gif图 具体步骤: 协议.税务和银行业务 信息填写 内购商品的添加 添加沙盒测试账号 内购代码的具体实现 内购的注意事 ...

  9. STM32的定时器详解(嵌入式学习)

    STM32的定时器详解 0. 前言 1. Systick定时器 概念 工作原理 时钟基准 Systick练习 2. HAL_Delay函数分析 3. 定时器 基本概念 定时器分类 定时器组成 计数器 ...

最新文章

  1. srm 593 dv2 1000pt
  2. IDEA创建maven JavaWeb工程
  3. python win+r时不成功_Win与R(不使用Anaconda的情况下)
  4. Python异常:TypeError: a bytes-like object is required, not 'str'
  5. LeetCode:62. 不同路径(python、c++)
  6. 初学Java,第一段代码
  7. Java判断隐藏文件
  8. ng-repeat动态生成的DOM如何获取宽度(封装好的方法)
  9. 20191110每日一句
  10. 最简单的基金理财讲解
  11. Python 爬虫学习笔记三:多页内容爬取内容分析及格式化
  12. h3c 抓包么 能通过debug_H3C debugging 使用技巧
  13. 通过naa在esxi主机上找到物理磁盘的位置
  14. WeMos TTGO WiFi + 蓝牙电池 ESP32 0.96 英寸 OLED点亮屏幕
  15. SQLMap用户常用命令——1
  16. mybatis中大于,小于,大于等于,小于等于,转义写法
  17. python用双重循环输出菱形图案_使用循环创建菱形图案
  18. 使用Kali上的Metasploit获取ssh登录到靶机权限
  19. python3切割圆形图片
  20. 打蚊子表情包_蚊子表情包 - 蚊子微信表情包 - 蚊子QQ表情包 - 发表情 fabiaoqing.com...

热门文章

  1. linux内核源码git操作简单总结
  2. 第01课:生活中的监听模式——一坑爹的热水器
  3. Bigger is Better
  4. webpack-dev-server配置host为WLAN地址(用于移动端调试)
  5. 广度优先搜索BFS——模板(附四维拓展:SDUT 3929魔戒)
  6. 16进制 两位两位转换
  7. 收藏一篇分析很到位的巨蟹座性格
  8. 【华为OD机试 2023】货币单位换算(C++ Java JavaScript Python)
  9. KeePass搭建一个私人密码库
  10. OPPO A31解账户锁刷机包 线刷教程