在创建测试项目以帮助获得我最近在SO (已删除)上询问的相关问题的答案后,我遇到了一个不同的,虽然类似的问题,当在一个内部旋转一个层时自定义UIView
子类。
可以看到iPhone模拟器会话的视频here。
该层看起来像是在x / y轴上以对角线旋转,而不是根据需要围绕z轴旋转。
执行旋转的代码位于名为setAngle:
的视图setter方法中,如下所示:
_imageLayer.transform = CATransform3DMakeRotation(angle / 180.0 * M_PI, 0.0, 0.0, 1.0);
(angle
以度为单位)。
完整的Xcode项目可用here。
原始的SO问题仅在设备方向改变后显示此行为,因此看起来我的理解上的差距比我最初想的要多(来自OSX背景,并且多次使用图层,我预计没有这样的问题)。
所以我的问题是:为什么图层不能根据需要围绕z轴旋转?
答案 0 :(得分:2)
我准备回答,但是你先发制人!无论如何,这里是我要说的(它真的解决了你的最后一点)
不可预测行为的主要原因是您正在转换对象上设置frame属性。这是你做不到的 - Apple警告它 * :在应用转换后,frame属性将返回未定义的结果。
所以你不应该这样做:
//_imageLayer.frame = layerFrame;
但设置bounds
和center
属性(在CALayers的情况下为position
)继续按预期工作,因此您可以执行以下操作:
_imageLayer.bounds = (CGRect){0,0,min,min};
_imageLayer.position = self.center;
<小时/> *在UIView中查看documentation的frame属性:
警告:如果transform属性不是标识转换,则此属性的值未定义,因此应忽略。
答案 1 :(得分:0)
好的,此问题现已修复。更新的项目是here。
所学问题是:
不要在视图控制器的viewWillLayoutSubviews
中设置视图的帧。 这可能是问题的根本原因。您不需要在自定义[ViewController _currentRect]
方法中执行任何计算,只要将自动调整大小掩码设置为拉伸视图到窗口界限。
不要在[UIView layoutSubviews]
中排列图层旋转时调用的图层(!!),这是低效的。相反,我使用[UIView setBounds:]
来布局图层。设备方向更改后会调用setBounds:
,但由于某些奇怪的原因,它不会在新创建的视图上调用,因此我会覆盖[UIView didMoveToSuperview]
以明确调用它(self.bounds = self.bounds;
)。 Curiouser和curiouser。
我设置了图层的bounds
和position
,而不是在铺设时设置图层的frame
,我认为这是根本原因(事情开始工作)在我这样做之后),但是我看不出这有什么不同,我认为这可以作为第一个项目符号中提到的错误的副作用而得到解决。 更新:正如@He中所指出的那样; 是的根本原因。
我不会将此答案标记为正确,因为我仍然感到有一种痛苦的感觉,即我的解决方案不是100%“正确”。