GeekerProbe

水滴石穿 Keeping faith.      --- wtlucky's Blog

Constraints & Transformations 在iOS7和8上的不同

| Comments

使用AutoLayout时,在iOS7iOS8上两者会有很大的不同,iOS8苹果优化了很多。最近看了一篇bolg,是Reveal的工程师写的介绍使用Constraints以及transform变幻之后在iOS78上的异同。

原文链接


先贴张图说明一下问题:

可以看到iOS7在使用了autolayout之后,进行transform变幻之后view并没有达到预期效果,而在iOS8和和纯frame布局的情况下是正常的。

autolayout使用的是Topleading与灰色的view进行约束,而frame是通过setCenter来设置位置的。

这种错误的现象会发生在iOS7及以前的版本中,在iOS8之后得到了修复。

通过Reveal查看可以看到:

使用autolayoutview跟他的参照View相比只移动了(-10,-10),而且它的布局位置也发生了偏移(10,10),在iOS8下查看,会发现布局位置并没有移动,跟参照View完全一致

由此可以得到的结论就是,在iOS78上使用autolayout布局的viewcenter属性的位置发生了改变。

通过设置断点和重写setFramesetCenter方法研究发现,在iOS78setFrame方法都没有被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方法没有没调用,因而viewtransform属性也就不是identity的,所以会出现问题。

至于具体的iOS78NSISLayoutEngine里面做了什么改变,可以查看博客原文

最后说一下结论:如果我们的app是使用iOS8或者以后的SDK编译链接的并且还要支持iOS7,并在没有identitytransformview上使用了AutoLayout。那么就应该注意一下几点:

  1. 如果只使用旋转和缩放的transform变换,那么就要使用CenterX/CenterY约束,来替代Top/Bottom/Left/Right/Trailing/Leading约束,因为如果transformview是通过它的centre布局的话,那么结果就有可能是正确的。
  2. 将要变换的view放到一个containerView里,然后用约束约束containerView好过直接约束变换的view。变换的view可以直接用代码布局,也可以用CentreX/CenterY约束。但是使用等宽等高与containerView建立约束将不会达到预期效果
  3. 不要使用constraint来约束这些View,使用autosizingMask,然后设置这些ViewtranslatesAutoresizingMaskIntoConstraintsYES

PS: 最后算是做个广告吧,Reveal这个工具真的是很NB很好用,当你使用了之后就会爱不释手。它可以查看view的层级关系,动态的改变UI属性,在最近的版本还支持对autolayout的支持,可以查看constraints已经对他们进行修改,我们做iOS开发的更多的是做界面开发工作,那么有了这样一个神器在手,那么必然会达到事半功倍的效果,工欲善其事,必先利其器!

Reveal还能做更NB的事情就是当你手机越狱后,然后你就可以查看任何app的视图层级关系了。就说到这里了,至于接下来怎样大家自己脑补吧。

既然这个工具这么强大,我们还是支持一下作者吧,同为开发者,都知道这行挺不容易的还是支持下正版吧,好消息是Reveal对中国的开发者们有个特惠价格:RMB249就可以拿下了,购买地址,比半价还优惠,我在知道这个消息后第一时间拿下了它,因为之前的价格确实有点贵,对我来说还是有压力的。

————————————

Comments