2013-02-16 106 views
3

创建测试项目后,为了帮助获取 相关问题的一些答案,我最近在SO (已删除)上询问,我遇到了一个不同的,虽然类似的问题,旋转一层自定义UIView子类。图层以x/y轴而不是z轴旋转

可以看到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

我得到了这个地方,它涉及如何设置图层'框架。如果我设置了“边界”和“位置”,那么图层就像平常一样旋转,但是这个关键似乎是获得了视图的宽度/高度,这说明了设备方向。这是我的理解缺乏的地方... – trojanfoe 2013-02-16 12:05:13

回答

2

我正要回答,但你抢先了我!反正这里是我说(它确实解决了你的最后一点)

的主要原因是不可预知的行为是要设置变换对象的框架属性。这是你不能做的 - 苹果警告它*:在应用变换之后,frame属性将返回未定义的结果。

,所以你不应该这样做:

//_imageLayer.frame = layerFrame; 

但设置boundscenter属性(CALayers的情况下position)继续按预期工作,因此,你可以做这样的事情:

_imageLayer.bounds = (CGRect){0,0,min,min}; 
    _imageLayer.position = self.center; 


*看到 documentation在UIView的框架属性:

警告:如果transform属性不是标识转换,则此属性的值未定义,因此应予以忽略。

+0

啊好的;我错过了,所以这是问题的根源。非常感谢。 – trojanfoe 2013-02-16 14:41:51

0

好的,现在这个问题已经修复。更新的项目是here

学到的问题是:

  • 不要从内设置视图的框架视图控制器的viewWillLayoutSubviews 这可能是问题的根源。 只要将autoresize掩码设置为将视图拉伸到窗口边界,您就不需要在自定义[ViewController _currentRect]方法中执行任何计算。

  • 不要将图层排列在[UIView layoutSubviews]中,因为在图层旋转(!!)时调用该图层效率不高。相反,我使用[UIView setBounds:]来布置图层。在设备方向更改后调用setBounds:,但出于某种奇怪的原因,它未在新创建的视图上调用,因此我忽略[UIView didMoveToSuperview]以显式调用它(self.bounds = self.bounds;)。 Curiouser和curiouser。

  • 我设置图层的boundsposition,而不是设置层的frame铺设的时候出来, 我认为是根源(事情开始工作,我这样做后),但我看不出这使得任何差异,我认为这是第一个要点 中提到的错误的副作用。 UPDATE:正如@He Was的答案中指出的那样;这的根本原因。

我不会将此答案标记为正确的,因为我仍然有一种疼痛的感觉,即我的解决方案不是100%“正确”。