2

所以,我似乎问了一些棘手的问题,但我又来了。

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

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

在此处输入图像描述

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

在此处输入图像描述

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

- (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 的分辨率呈现,因此一切看起来都很模糊:

在此处输入图像描述

我认为这与转换有关,但我不确定如何或为什么。如果我在旋转设置回 0 弧度后将图层变换设置为标识(因此它完全在视图中),则视图将捕捉到其正确位置。我还注意到,在 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);

产生这个: 在此处输入图像描述

4

2 回答 2

1

我想到了。我一直在努力使用的视图控制器位于我作为自定义拆分视图控制器构建的自定义容器控制器中。在视图窗格之间切换时,该控制器还利用了 3D 变换。在过渡结束时,我单独留下了 .m34(透视变换)。显然这导致了我遇到的所有问题。在容器控制器中切换视图时,我确保将图层的转换设置为标识,现在一切正常。

所以我想这个故事的寓意是,在你转换任何子层之前,始终确保你的超级层处于身份转换,否则你可能会得到意想不到的结果。

于 2012-03-21T22:37:05.090 回答
0

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

于 2012-03-21T18:48:34.137 回答