Основная графика на Retina-дисплее с 3D-преобразованием - PullRequest
2 голосов
/ 21 марта 2012

Итак, я, кажется, задаю сложные вопросы, но здесь я иду снова.

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

enter image description here

Я думаю, что это как-то связано с преобразованием, но я не уверен, как и почему.Если я установлю преобразование слоя в идентичность после того, как вращение вернется к 0 радианам (так, чтобы оно было полностью видно), представление вернется в правильное положение.Я также отметил, что при 0 радианах преобразование не совсем идентично: m34 (в перспективе) все еще установлен.Установка его на ноль устраняет проблему.Но установка его в ноль во время не устраняет проблему, пока вид находится в любом другом вращении, кроме 0 рад.И представления, которые не вращаются вниз от источника {0,0}, все еще смещены.Кажется, что проблема возникает во время ЛЮБОГО трехмерного преобразования, хотя я проверил все преобразования, чтобы подтвердить это.

ОБНОВЛЕНИЕ

Из-заответ @Joshua Weinberg Я начал возиться со шкалой растеризации слоя.Я обнаружил, что смещение базового изображения было отключено на 1 / rasterizationScale.Поэтому, если я установлю растеризацию Scale на 6 и переместу свой вид вниз на 30, фоновое изображение сместится только на 30/6 (5,0f).

UPDATE 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 ]

1 голос
/ 22 марта 2012

Я понял это.Контроллер представления, с которым я боролся, был в Контроллере Пользовательского Контейнера, который я построил как пользовательский контроллер разделения представления.Этот контроллер также использовал 3D-преобразования при переключении между панелями просмотра.В конце перехода я оставил .m34 (перспективное преобразование) в покое.Видимо, это было причиной всех проблем, которые у меня были.Я удостоверился, что установил преобразование слоя в идентичность при переключении представлений в контроллере контейнера, и теперь все это прекрасно работает.

Так что я думаю, что мораль этой истории в том, что всегда убедитесь, что ваши суперслойпреобразование идентичности до того, как вы преобразуете какие-либо подслои, иначе у вас могут быть неожиданные результаты.

0 голосов
/ 21 марта 2012

Установите rasterizationScale слоя на [[UIScreen mainScreen] scale], и оно должно работать.Когда вы применяете 3d-преобразование, слой растеризуется, и растеризация по умолчанию равна 1.0f;

...