所以,我似乎问了一些棘手的问题,但我又来了。
我有一个看起来很奇怪的问题。在我的一些观点中,我通过将工具栏在 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);
产生这个: