原文地址:http://www.pluto-y.com/wwdc-2015-mystries-of-auto-layout/
继续前一篇文章所讲的技巧,接下来将剩下的六个技巧。
技能点七:Layout的周期
关于布局周期这里主要是针对修改布局的情况下,其实主要就分为以下三个步骤,并且这三个步骤之间形成一个循环。具体如下:
先是约束变化,然后会产生一个延迟的布局事件,最后到达App的循环。而其中App的循环又会继续等待约束变化的过程,从而产生一个新的周期。
约束变化
针对这里的约束变化主要包括以下几种:
* Activating和Deactivating约束
* 设置约束的constant或者priority
* 添加或者删除视图
以上这几种的约束都会产生一个新的布局周期。会根据以下的变化重新计算布局,Layout的引擎则会根据计算的结果接收到新的布局变量,而视图就会自动去调用superview.setNeedsLayout()
。这些步骤就组成了约束变化的过程。
延迟的布局事件
延迟布局的通过主要包括以下几个步骤:
* 重新放置那些错放的视图
* 更新约束并且重新给视图的frame赋值
当然除了约束变化会导致延迟布局的事件以外,还可以通过setNeedsUpdateConstraints()
来触发布局事件。
并且在苹果官网还是强烈建议使用Activating Contraints
和Deactivating Contraints
而不是去Change Contraints
(即Add 或者Remove约束),毕竟前者比后者来说说速度快多了。小伙伴们以后要习惯用Activating 和 Deactivating来修改约束。
关于layoutSubviews
(在Mac OX中叫做layout
)的方法的作用主要在于让布局引擎接受到新的布局的约束值,而不是重新排布各个视图的位置。并且将新的值设定到各个子视图中(在iOS中用的是setBounds
和setCenter
在Mac OX中用的是setFrame
)
而如果在重写layoutSubviews
的过程中需要注意以下几点:
* 必须调用[super layoutSubviews]
的方法
* 修改视图的布局需要在调用[super layoutSubviews]
之前进行修改
* 别调用setNeedsUpdateConstraints
* 别修改不是属于该视图的子视图
* 别随意的修改约束
然而这个技能点主要是讲解了一些理论上的知识,而博主对此也不是有非常深刻的理解,所以可能讲解的有些不是特别好,望大家见谅。不过一些注意点是大家都需要注意的,麻烦大家记一下。
技能点八:与之前的适配进行交互
对于此来说,iOS关于布局最先是通过setFrame
来进行布局,之后在此基础上添加了一个autoresizingMask
来进行根据父视图的修改来调整子视图的布局,最后在近几个版本中添加了一个Auto Layout
的布局机制,主要是通过约束来进行布局。而技能点八主要是针对那些就的布局机制与AutoLayout共存情况下的一些情况的注意点。
当然在Auto Layout下,小伙伴们依然可以用setFrame
来进行布局,但是在之后可能会有个延迟布局的事件来回调的情况下,可能您的setFrame
会出现失效的情况。然后对于那些小伙伴们真的希望通过setFrame
来进行布局的控件来说苹果有提供一个变量进行处理该种情况。这个变量就是translatesAutoresizingMaskIntoConstraints
,如果在创建某个视图是通过IB的情况下,它的默认值就是NO
,而如果在创建某个视图是通过代码的情况下,它的默认值则就是YES
。而如果小伙伴们想在代码中添加或声明约束给代码生产的视图的话,即的将这个变量设置为NO,否会出现报错的情况,如下图的情况下:
其实只需要将translatesAutoresizingMaskIntoConstraints
设置成NO
即可。正确的代码如下:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
//别忘了将这个变量设置成NO
btn.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:btn];
NSLayoutConstraint *kTopContraints = [NS