使用AutoLayout
时,在iOS7
和iOS8
上两者会有很大的不同,iOS8
苹果优化了很多。最近看了一篇bolg
,是Reveal
的工程师写的介绍使用Constraints
以及transform
变幻之后在iOS78
上的异同。
先贴张图说明一下问题:
可以看到iOS7
在使用了autolayout
之后,进行transform
变幻之后view
并没有达到预期效果,而在iOS8
和和纯frame
布局的情况下是正常的。
autolayout
使用的是Top
和leading
与灰色的view
进行约束,而frame
是通过setCenter
来设置位置的。
这种错误的现象会发生在iOS7
及以前的版本中,在iOS8
之后得到了修复。
通过Reveal
查看可以看到:
使用autolayout
的view
跟他的参照View
相比只移动了(-10,-10)
,而且它的布局位置也发生了偏移(10,10)
,在iOS8
下查看,会发现布局位置并没有移动,跟参照View
完全一致
由此可以得到的结论就是,在iOS7
和8
上使用autolayout
布局的view
的center
属性的位置发生了改变。
通过设置断点和重写setFrame
和setCenter
方法研究发现,在iOS7
和8
上setFrame
方法都没有被UIKit
调用到,而只有setCenter
方法被调用。
“If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.”
————UIView’s Class Reference
如果transform
属性不是identity
的,那么他的值就是不确定的而且应该被忽略。因此可以断定setFrame
方法没有没调用,因而view
的transform
属性也就不是identity
的,所以会出现问题。
至于具体的iOS7
和8
在NSISLayoutEngine
里面做了什么改变,可以查看博客原文。
最后说一下结论:如果我们的app
是使用iOS8
或者以后的SDK
编译链接的并且还要支持iOS7
,并在没有identity
的transform
的view
上使用了AutoLayout
。那么就应该注意一下几点:
- 如果只使用旋转和缩放的
transform
变换,那么就要使用CenterX/CenterY
约束,来替代Top/Bottom/Left/Right/Trailing/Leading
约束,因为如果transform
的view
是通过它的centre
布局的话,那么结果就有可能是正确的。 - 将要变换的
view
放到一个containerView
里,然后用约束约束containerView
好过直接约束变换的view
。变换的view
可以直接用代码布局,也可以用CentreX/CenterY
约束。但是使用等宽等高与containerView
建立约束将不会达到预期效果 - 不要使用
constraint
来约束这些View
,使用autosizingMask
,然后设置这些View
的translatesAutoresizingMaskIntoConstraints
为YES
。
PS:
最后算是做个广告吧,Reveal
这个工具真的是很NB
很好用,当你使用了之后就会爱不释手。它可以查看view
的层级关系,动态的改变UI
属性,在最近的版本还支持对autolayout
的支持,可以查看constraints
已经对他们进行修改,我们做iOS
开发的更多的是做界面开发工作,那么有了这样一个神器在手,那么必然会达到事半功倍的效果,工欲善其事,必先利其器!
Reveal
还能做更NB的事情就是当你手机越狱后,然后你就可以查看任何app
的视图层级关系了。就说到这里了,至于接下来怎样大家自己脑补吧。
既然这个工具这么强大,我们还是支持一下作者吧,同为开发者,都知道这行挺不容易的还是支持下正版吧,好消息是Reveal对中国的开发者们有个特惠价格:RMB249
就可以拿下了,购买地址,比半价还优惠,我在知道这个消息后第一时间拿下了它,因为之前的价格确实有点贵,对我来说还是有压力的。
————————————