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的更多相关文章

  1. XE6移动开发环境搭建之IOS篇(8):在Mac OSX 10.8中安装XE6的PAServer(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 安装PAServer ...

  2. XE6移动开发环境搭建之IOS篇(7):在Mac OSX 10.8中安装Xcode4.6.3(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 在安装Xcode前, ...

  3. 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系列的移动开发环境的 ...

  4. XE6移动开发环境搭建之IOS篇(6):设置Mac OSX的网络。(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 我们配置一下MAC的 ...

  5. XE6移动开发环境搭建之IOS篇(5):解决Windows和虚拟机下Mac OSX的共享问题(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 在安装XE6 PAS ...

  6. XE6移动开发环境搭建之IOS篇(4):VMware9里安装Mac OSX 10.8(有图有真相)

    网上能找到的关于Delphi XE系列的移动开发环境的相关文章甚少,本文尽量以详细的图文内容.傻瓜式的表达来告诉你想要的答案. 原创作品,请尊重作者劳动成果,转载请注明出处!!! 以下内容比较长,我们 ...

  7. 在OSX狮子(Lion)上安装MYSQL(Install MySQL on Mac OSX)

    这篇文章简述了在Mac OSX狮子(Lion)上安装MySQL Community Server最新版本v10.6.7的过程. MySQL是最流行的开源数据库管理系统.首先,从MySQL的下载页面上下 ...

  8. Commandline OpenVPN client on Mac OSX with macports

    http://www.tuicool.com/articles/FjuyQj  注:文中有些内容做了修改,特别是那个配置文件,不能直接抄着用. Most people use TunnelBrick ...

  9. rapoo mt700键盘mac osx不能复制问题

    问题描述:rapoo mt700键盘mac osx,按windows建+c不能复制,其它按键正常 解决办法:检查右上角windows等是否亮,如果是亮着按FN+WIN 切换模式 操作方法: 有线模式: ...

随机推荐

  1. java ftp下载文件

    1.使用官方正规的jar commons-net-1.4.1.jar jakarta-oro-2.0.8.jar 注意:使用ftp从windows服务器下载文件和从linux服务器下载文件不一样 2. ...

  2. linux查看磁盘系统df,du

    可以用df命令轻松地查看所有已挂载磁盘的使用情况 df df -h 把输出的文件单位换成文件可读的单位 du 命令显示特定目录的使用情况 du -c 显示总用量 du -h 人类可读性 du -s 每 ...

  3. Web_add_header

    如果你发现所有的HTTP send请求都缺少头数据包,在脚本中的开头添加web_add_auto_header(”XXXXX“,”yyyy“);随着web_add_auto_header的添加,你不需 ...

  4. 安装Ifconfig

    1.ifconfig 2.whereis 检查 3.yum search ifconfig 4.分割线下面让我们安装 net-tools.x86_64 执行 yum -y install net-to ...

  5. Sql Server2005新特性及性能

    举几个例子来简单说明 这些例子我引用了Northwind库. 1. TOP 表达式 SQL Server 2000的TOP是个固定值,是不是觉得不爽,现在改进了. --前n名的订单declare @n ...

  6. iptables命令详解和举例

    网上看到这个配置讲解得还比较易懂,就转过来了,大家一起看下,希望对您工作能有所帮助.网管员的安全意识要比空喊Linux安全重要得多. iptables -Fiptables -Xiptables -F ...

  7. 我的android学习经历36

    最近把android的基础知识都学的差不多了,也写了许多demo,就想自己写一个app,可是写到后面的时候发现很混乱,所以还是得写一些文档,用xml语言写一下基础的类以及一些其他的东西.所以要想写一个 ...

  8. 2. Swift元组|可选值|断言

    1. 元组英文名字 Tuple,将多个数据类型(任意类型)组合成一个数据,与c语言的中的机构体有几分相似,功能也是非常强大的,尤其是在定义请求参数,状态之类的地方经常用到. let http404Er ...

  9. LTE Module User Documentation(翻译14)——Uplink Power Control(上行功率控制)

    LTE用户文档 (如有不当的地方,欢迎指正!) 20 Uplink Power Control(上行功率控制)   上行功率控制功能默认是开启的.用户可以通过设置布尔属性 ns3::LteUePhy: ...

  10. fifter常见的运用场景

    没配置过滤器 package servlet; import java.io.IOException; import javax.servlet.ServletException; import ja ...