Звучит так, будто вы хотите, чтобы представление всегда отображало его содержимое в одной и той же ориентации относительно устройства , независимо от ориентации интерфейса (строка состояния и т. Д.). Так что на ваших изображениях, если «привет» рисуется с помощью «h» с помощью кнопок физической громкости, то вы всегда хотите, чтобы «h» рисовали с помощью кнопок физической громкости, даже если пользователь повернул устройство (и остальные пользовательский интерфейс повернулся).
iOS вращает пользовательский интерфейс, устанавливая преобразование представления вашего корневого контроллера. Вы можете проверить это в отладчике:
# Unrotated
(lldb) po [[(id)UIApp keyWindow] recursiveDescription]
(id) $1 = 0x0b535030 <UIWindow: 0xd434a80; frame = (0 0; 320 480); layer = <UIWindowLayer: 0xd434b70>>
| <UIView: 0xb5385e0; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0xb538710>>
# Rotated with home button at the left
(lldb) po [[(id)UIApp keyWindow] recursiveDescription]
(id) $2 = 0x0f036060 <UIWindow: 0xd434a80; frame = (0 0; 320 480); layer = <UIWindowLayer: 0xd434b70>>
| <UIView: 0xb5385e0; frame = (20 0; 300 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0xb538710>>
Таким образом, вы можете отменить это, применив обратное преобразование к вашему графическому контексту, прежде чем рисовать ваш контент. Но вы также должны скорректировать происхождение вашего графического контекста, что делает его немного хитрее.
Во-первых, вам нужно переместить начало координат в центр вида. Затем вы применяете обратное преобразование, чтобы отменить поворот интерфейса. Затем вы перемещаете источник назад. Предполагая, что ваш CGLayer
имеет тот же размер, что и ваш вид (в портретной ориентации), это должно работать:
- (void)drawRect:(CGRect)rect
{
if (!_cgLayer) {
[self initCGLayer];
}
CGContextRef gc = UIGraphicsGetCurrentContext();
CGContextSaveGState(gc); {
CGSize mySize = self.bounds.size;
CGSize cgLayerSize = CGLayerGetSize(_cgLayer);
CGContextTranslateCTM(gc, mySize.width / 2, mySize.height / 2);
CGContextConcatCTM(gc, CGAffineTransformInvert(self.window.rootViewController.view.transform));
CGContextTranslateCTM(gc, -cgLayerSize.width / 2, -cgLayerSize.height / 2);
CGContextDrawLayerAtPoint(gc, CGPointZero, _cgLayer);
} CGContextRestoreGState(gc);
}
Это не идеально. Это заканчивается рисованием, как я сказал: всегда в той же ориентации относительно устройства. Однако из-за способа поворота интерфейса пользователь поворачивает устройство, он перерисовывает изображение, повернутое на 90 градусов, и поворачивает изображение в правильную ориентацию.
Я поместил тестовый проект здесь:
https://github.com/mayoff/stackoverflow-cglayer-unrotating
В тестовом проекте вы видите полупрозрачную панель инструментов, которая работает нормально - она поворачивается к краю экрана, ближайшему к земле. Под этим подразумевается представление, которое использует метод drawRect:
, описанный выше, для компенсации вращения пользовательского интерфейса.