Итак, кажется, я задаю трудные вопросы, но вот опять.
У меня, кажется, странная проблема. В некоторых представлениях я скрываю панели инструментов вверху, поворачивая их назад по оси x на 90 градусов. Затем я разрешаю пользователю «опускать» их, что повернет вид на 0 градусов, отображая панель инструментов. Все отлично работает, за исключением одного вида, где у меня есть две панели инструментов, которые нужно опустить. Это работает путем поворота первой панели инструментов вниз, а затем второй, при этом первая панель инструментов смещается вниз на высоту второй панели инструментов. Все это прекрасно работает на дисплеях без ретина. Однако на дисплее сетчатки смещение первой панели инструментов вдвое меньше, чем должно быть. Кроме того, рамка представления именно такая, какой она должна быть. Другими словами, когда я проверяю (NSLog), я получаю кадр {0, 30, 320, 30}, но фактическое изображение отображается в кадре: {0, 15, 320, 30}. Меняется только фон. Если я нажму на место, где должно быть представление, пройдут события касания.
Вот что происходит на экранах Retina:

Вот что происходит на экранах без 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;
}
Опять же, это происходит только на дисплеях Retina.
Теперь панель инструментов отображается в Core Graphics. Поэтому я устранил свой CG-код как источник проблемы, полностью удалив его из drawRect, чтобы вообще не было никакого кода в draw rect; проблема все еще возникает. Я также заметил, что если я не использую drawRect (закомментируйте весь метод), вращение происходит правильно, но все подпредставления (которые также используют основную графику) отображаются с разрешением 1/2, так что все выглядит размытым:

Я думаю, что это как-то связано с преобразованием, но я не уверен, как и почему. Если я установлю преобразование слоя в идентичность после того, как вращение вернется к 0 радианам (чтобы оно было полностью в поле зрения), вид привяжется к своему правильному положению. Я также заметил, что при 0 радианах трансформация не совсем идентична: m34 (перспектива) все еще установлена. Установка его на ноль решает проблему. Но установка его на ноль во время не решает проблему, пока вид находится в любом другом вращении, кроме 0 рад. А представления, которые не вращаются вниз от исходной точки {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);
Выдает следующее: 