iOS: как я могу повернуть CGLayer?
Я искал ответ повсюду. Я до сих пор набираю скорость на iOS-разработчике, так что я могу с уверенностью признать, что здесь я могу быть без одежды. Тем не менее, полное и полное отсутствие ответов заставляет меня задуматься, есть ли на самом деле ответ.
Вот в чем дело: я использую CGLayer для генерации довольно простого векторного многоугольника:
- (CGLayerRef)getASegment
{
CGSize layerSize = s_viewRects[kASegment].size;
CGLayerRef theLayer = CGLayerCreateWithContext ( UIGraphicsGetCurrentContext(),
layerSize, nil );
CGContextRef context = CGLayerGetContext ( theLayer );
CGContextAddLines ( context, s_shapePoints, 7 );
return theLayer;
}
s_viewRects - это статический массив, в котором хранятся фрагменты контейнера, помещенные в общее изображение, а s_shapePoints содержит массив структур CGPoint, которые отображают искаженный шестиугольник.
Теперь я хочу повторно использовать эту форму. Его необходимо перевернуть и повернуть, чтобы он соответствовал всем требованиям (для записи это "сегменты" на "светодиодном" дисплее).
Я в порядке. Нет проблем.
Проблема в том, чтобы повернуть его для повторного использования. Кажется, нет никакого способа вращать CGLayer. Много способов вращать CALayers, но не CGLayers. Я был бы счастлив использовать CALayer, за исключением того, что CALayers, кажется, все сосредоточены на растровой графике, и мне нужна векторная графика.
Я уверен, что должен быть очевидный способ решить эту проблему. Пока что я видел только один способ - повернуть весь целевой графический контекст, нарисовать фигуру, а затем развернуть контекст. Эквивалент поворота дома, чтобы открутить лампочку.
Единственный способ заставить его работать, это на самом деле преобразовать точки, прежде чем рисовать каждый сегмент отдельно, что означает отсутствие повторного использования. Выполнение CGContextRotateCTM во время создания фигуры фактически не приводит к повороту элемента при отображении.
Есть какие-нибудь подсказки?
2 ответа
Пока что я видел только один способ - повернуть весь целевой графический контекст, нарисовать фигуру, а затем развернуть контекст. Эквивалент поворота дома, чтобы открутить лампочку.
Я уверен, что это ваше решение. Это как рисовать с CGContextRef
работает.
Я был бы счастлив использовать CALayer, за исключением того, что CALayers, кажется, все сосредоточены на растровой графике, и мне нужна векторная графика.
Вы пытались использовать CAShapeLayer
?
ОК, как и обещал, вот код.
Сначала я использую CAShapeLayer и создаю его способом, подобным приведенному выше:
- (CALayer *)getSegment
{
CGRect layerFrame = CGRectMake ( 0, 0, s_viewRects[kASegment].size.width, s_viewRects[kASegment].size.height );
CAShapeLayer *ret = [CAShapeLayer layer];
[ret setFrame:layerFrame];
CGMutablePathRef thePath = CGPathCreateMutable ();
CGPathAddLines ( thePath, nil, s_shapePoints, 7 );
[ret setPath:thePath];
return ret;
}
Затем я установил его в основной слой, выполнив преобразование по пути:
_top_left_element = [self getSegment];
frame = [self calculateRectForElement:_top_left_element];
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, M_PI_2, 0.0, 0.0, -1.0 );
[_top_left_element setTransform:transform];
[_top_left_element setFrame:frame];
[_main_element addSublayer:_top_left_element];
CATransform3DRotate необходим, так как свойство transform слоя является трехмерным. Я использую M_PI_2, так как все преобразования в радианах (M_PI_2 - удобный макрос, который означает "90°"), а -1 будет вращать против часовой стрелки.
CalculateRectForElement - это функция, которая выясняет, где все находится. Он просто возвращает прямоугольник, который позиционирует элемент.
_top_left_element - это свойство класса, которое является CALayer*.
Я сделал это, и Бьорн Стронгинтерам твой дядя.
ОБНОВЛЕНИЕ: Я хотел добавить, что вам нужно убедиться, что вы CGPath отпустили пути слоя при выгрузке / уничтожении, иначе вы получите утечку.