Retina上的核心图形显示3D变换

时间:2012-03-21 16:22:22

标签: objective-c core-graphics catransform3d

所以,我似乎提出了难以回答的问题,但我又来了。

我有一个看似奇怪的问题。在我的一些观点中,我通过将工具栏在x轴上向后旋转90度来隐藏工具栏。然后我允许用户“拉下”它们将视图旋转到0度,从而显示工具栏。这一切都很有效,除了在一个视图中我有两个工具栏可以拉下来。这可以通过向下旋转第一个工具栏然后向下旋转第二个工具栏,第一个工具栏向下移动第二个工具栏的高度。所有这些在非视网膜显示器上都能正常工作。然而,在视网膜显示器上,第一个工具栏的位移只是它应该的一半。此外,视图的框架正是它应该是的。换句话说,当我检查(NSLog)时,我得到{0, 30, 320, 30}的帧,但实际图像显示在帧:{0, 15, 320, 30}。这只是背景的转移。如果我点击视图应该是的空间,触摸事件就会通过。

这就是视网膜屏幕上发生的事情:

enter image description here

这是在非Retina屏幕上发生的事情(完全相同的代码):

enter image description here

这是我用来旋转视图的代码(非常简单):

- (void) rotateView:(UIView *)view downBy:(CGFloat)rad{
    CALayer *rLayer = view.layer;
    CGFloat zDist = self.view.window.bounds.size.height * 1.5f;
    CATransform3D rT = CATransform3DIdentity;
    rT.m34 = 1.0f /  -zDist;
    rT = CATransform3DRotate(rT, rad, 1.0f, 0.0f, 0.0f);
    rLayer.transform = rT;
}

同样,这只发生在视网膜显示器上。

现在,工具栏正在Core Graphics中呈现。所以我通过从drawRect中完全删除它来消除我的CG代码作为问题的根源,因此在draw rect中根本没有代码;问题仍然存在。我还注意到,如果我不使用drawRect(注释掉整个方法)旋转正确,但所有子视图(也使用核心图形)都以1/2的分辨率渲染,这样一切看起来都很模糊: / p>

enter image description here

我认为它与变换有关,但我不确定如何或为什么。如果我在将旋转设置回0弧度(因此它完全在视图中)后将图层变换设置为identity,则视图将捕捉到其正确位置。我还注意到,在0弧度处,变换并不完全相同:仍然设置m34(透视)。将其设置回零确实可以解决问题。但是在视图处于0 rad以外的任何其他旋转时,将其设置为零并不能解决问题。并且未从原点{0,0}向下旋转的视图仍会移位。似乎问题发生在任何3d变换期间,尽管我已经检查了所有变换以确认它。

更新

由于@Joshua Weinberg的回答,我开始搞乱图层的rasterizationScale。我发现底层图像的偏移是1 / rasterizationScale。因此,如果我将rasterizationScale设置为6并将视图向下移动30,则背景图像仅向下移动30/6(5.0f)。

更新2

我尝试了一个黑客,我将图像翻译下来。它的工作原理是图像向下移动了适当的数量,但它也使图像消失。所以这个代码在我的旋转方法中:

rT = CATransform3DTranslate(rT, view.frame.origin.x - (view.frame.origin.x / rLayer.rasterizationScale), view.frame.origin.y - (view.frame.origin.y / rLayer.rasterizationScale), 0);

收益率: enter image description here

2 个答案:

答案 0 :(得分:1)

我明白了。我一直在苦苦挣扎的视图控制器是我自定义容器控制器,我已经构建为自定义拆分视图控制器。该控制器还在视图窗格之间切换时使用3D变换。在过渡结束时,我独自离开了.m34(透视变换)。显然,这导致了我所遇到的所有问题。我确保在容器控制器中切换视图时将图层的变换设置为identity,现在一切正常。

所以我猜这个故事的寓意是,在变换任何子图层之前,一定要确保你的超级图层处于身份变换状态,否则你可能会产生意想不到的结果。

答案 1 :(得分:0)

将图层的rasterizationScale设置为[[UIScreen mainScreen] scale],它应该可以使用。应用3d变换时,图层将被栅格化,默认光栅化为1.0f;