The Layout Process on Mac OSX and iOS
First we will recap the steps it takes to bring views on screen with Auto Layout enabled. When you’re struggling to produce the kind of layout you want with Auto Layout, specifically with advanced use cases and animation, it helps to take a step back and to recall how the layout process works.
Compared to working with springs and struts, Auto Layout introduces two additional steps to the process before views can be displayed: updating constraints and laying out views. Each step is dependent on the one before; display depends on layout, and layout depends on updating constraints.
The first step – updating constraints – can be considered a “measurement pass.” It happens bottom-up (from subview to super view) and prepares the information needed for the layout pass to actually set the views’ frame. You can trigger this pass by calling setNeedsUpdateConstraints. Any changes you make to the system of constraints itself will automatically trigger this. However, it is useful to notify Auto Layout about changes in custom views that could affect the layout. Speaking of custom views, you can override updateConstraints to add the local constraints needed for your view in this phase.
The second step – layout – happens top-down (from super view to subview). This layout pass actually applies the solution of the constraint system to the views by setting their frames (on OS X) or their center and bounds (on iOS). You can trigger this pass by calling setNeedsLayout, which does not actually go ahead and apply the layout immediately, but takes note of your request for later. This way you don’t have to worry about calling it too often, since all the layout requests will be coalesced into one layout pass.
To force the system to update the layout of a view tree immediately, you can call layoutIfNeeded/layoutSubtreeIfNeeded (on iOS and OS X respectively). This can be helpful if your next steps rely on the views’ frame being up to date. In your custom views you can override layoutSubviews/layout to gain full control over the layout pass. We will show use cases for this later on.
Finally, the display pass renders the views to screen and is independent of whether you’re using Auto Layout or not. It operates top-down and can be triggered by calling setNeedsDisplay, which results in a deferred redraw coalescing all those calls. Overriding the familiar drawRect: is how you gain full control over this stage of the display process in your custom views.
Since each step depends on the one before it, the display pass will trigger a layout pass if any layout changes are pending. Similarly, the layout pass will trigger updating the constraints if the constraint system has pending changes.
It’s important to remember that these three steps are not a one-way street. Constraint-based layout is an iterative process. The layout pass can make changes to the constraints based on the previous layout solution, which again triggers updating the constraints following another layout pass. This can be leveraged to create advanced layouts of custom views, but you can also get stuck in an infinite loop if every call of your custom implementation of layoutSubviews results in another layout pass.
- setNeedsUpdateConstraints makes sure a future call to updateConstraintsIfNeeded calls updateConstraints.
- setNeedsLayout makes sure a future call to layoutIfNeeded calls layout(在iOS上是 layoutSubviews).
如果我们实现一个Custom View,并且这个Custom view会在加载nib后需要更新一个constraints(添加或者删除),那这个CustomView 应该 overrid updateConstraints方法,在这个方法中,将需要update 的constraints设置完成后,调用setNeedsUpdateConstraints: (?在哪里调用呢?),通知下次的 measurement pass时custom view 的updateConstraints会被调用到。
如果你的Custom View需要自定义的layout行为时,你才需要override layout方法(在iOS上是layoutSubViews),并且调用setNeedsLayout: 方法通知Layout pass能调用到custom view 的layout方法。如果不override layout方法,那几乎没有任何需要调用setNeedsLayout:,因为如果constaint有任何变化,layout pass会调用updateConstraintsIfNeeded并完成constraint 的更新,然后根据constraint的变化进行layout。所以说,底层的变化会被监测到,本层又没有什么特殊,那就没必要使用setNeedsLayout:。
如果你的代码需要对于constraint的更新立刻反应到constraint上,那你应该调用updateConstraintsIfNeeded,如果需要立刻反应到layout上,那应该调用layoutIfNeeded,如果希望立刻反应到Display上,应该调用啥呢?事实上,这是不允许的,所有的draw必须遵照cycle来,调用setNeedsDisplay可以让这个view在下一个draw cycle时被redraw,但是没有API可以让draw立刻发生。
Reference:
1. http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html
2. https://developer.apple.com/library/mac/releasenotes/UserExperience/RNAutomaticLayout/
The Layout Process on Mac OSX and iOS的更多相关文章
- XE6移动开发环境搭建之IOS篇(8):在Mac OSX 10.8中安装XE6的PAServer(有图有真相)
网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 安装PAServer ...
- XE6移动开发环境搭建之IOS篇(7):在Mac OSX 10.8中安装Xcode4.6.3(有图有真相)
网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 在安装Xcode前, ...
- XE6移动开发环境搭建之IOS篇(7):在Mac OSX 10.8中安装XE6的PAServer(有图有真相)
XE6移动开发环境搭建之IOS篇(7):在Mac OSX 10.8中安装XE6的PAServer(有图有真相) 2014-08-22 21:06 网上能找到的关于Delphi XE系列的移动开发环境的 ...
- XE6移动开发环境搭建之IOS篇(6):设置Mac OSX的网络。(有图有真相)
网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 我们配置一下MAC的 ...
- XE6移动开发环境搭建之IOS篇(5):解决Windows和虚拟机下Mac OSX的共享问题(有图有真相)
网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 在安装XE6 PAS ...
- XE6移动开发环境搭建之IOS篇(4):VMware9里安装Mac OSX 10.8(有图有真相)
网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 以下内容比较长,我们 ...
- 在OSX狮子(Lion)上安装MYSQL(Install MySQL on Mac OSX)
这篇文章简述了在Mac OSX狮子(Lion)上安装MySQL Community Server最新版本v10.6.7的过程. MySQL是最流行的开源数据库管理系统.首先,从MySQL的下载页面上下 ...
- Commandline OpenVPN client on Mac OSX with macports
http://www.tuicool.com/articles/FjuyQj 注:文中有些内容做了修改,特别是那个配置文件,不能直接抄着用. Most people use TunnelBrick ...
- rapoo mt700键盘mac osx不能复制问题
问题描述:rapoo mt700键盘mac osx,按windows建+c不能复制,其它按键正常 解决办法:检查右上角windows等是否亮,如果是亮着按FN+WIN 切换模式 操作方法: 有线模式: ...
随机推荐
- openDatabase() chrome vivaldi Stylish
located at /Users/ruili/Library/Application Support/Vivaldi/Default/databases/ Databases.db contains ...
- ambari之hbase数据迁移
一.hbase原理剖析 Base是一个构建在HDFS上的分布式列存储系统:HBase是基于Google BigTable模型开发的,典型的key/value系统:HBase是Apache Hadoop ...
- c++11中的for简化用法
1.序列for循环 map<string,int> m{{"a",1},{"b",2},{"c",3}} for(auto p: ...
- 在Outlook中修改IMAP邮件账户的存储位置
使用Outlook收发邮件,但是不想把邮件保存在默认的C盘. 对于POP3账户,Outlook提供了变更数据文件目录的方法,但是IMAP账户无法修改. 网上搜索了很多资料,终于找到一个可行的办法,整理 ...
- 由“单独搭建Mybatis”到“Mybatis与Spring的整合/集成”
在J2EE领域,Hibernate与Mybatis是大家常用的持久层框架,它们各有特点,在持久层框架中处于领导地位. 本文主要介绍Mybatis(对于较小型的系统,特别是报表较多的系统,个人偏向Myb ...
- javascript guid(uuid)
http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript function generateU ...
- python走起之第二话
Python基础 一.整数(int) 如: 18.73.84 整数类的功能方法及举例: 带__的方法代表有多种表达方式 1.__abs__ <==> abs() 求整数的绝对值:(-11) ...
- http://www.oreilly.com/catalog/errataunconfirmed.csp?isbn=9780596529321
集体智慧勘误表: http://www.oreilly.com/catalog/errataunconfirmed.csp?isbn=9780596529321 ------------------- ...
- Deep Learning 15:RBM的学习
RBM是深度学习的核心,所以必须彻底清楚地理解RBM原理.推导及其训练方法 1.读学位论文“基于深度学习的人脸识别研究”: 对RBM.DBN的介绍比较详细,可以作为基础阅读,再去读英文论文. 2.RB ...
- CSS cursor属性
介绍: 该属性规定要显示的光标的类型,该属性定义了鼠标指针放在一个元素边界范围之内的时候所用的光标的形状. 常用的属性值: default:默认光标 auto:浏览器默认的光标 pointer:光标呈 ...