2012-07-02 2 views
0

Я искал широкий ответ для ответа. Я все еще прихожу на скорость для iOS-разработчика, поэтому я могу определенно согласиться с тем, что я могу быть без ума отсюда. Однако полная и полная нехватка ответов заставляет меня задаться вопросом, действительно ли есть ответ.iOS: Как я могу повернуть CGLayer?

Вот сделка: я использую 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 во время создания фигуры фактически не приводит к вращению элемента при его отображении.

Любые подсказки?

+0

вздох ... «cloo» был шуткой. –

+0

Математическая речь: поворот дома не отличается от поворота лампочки :) - Вы также можете использовать объект CGPath и добавлять CGAffinetransform каждый раз, когда вы добавляете/рисуете Path, а также CGLayer также фокусируется на растровой графике. –

ответ

1

Единственный способ, который я видел до сих пор, состоит в том, чтобы повернуть весь целевой графический контекст, нарисовать фигуру, а затем не вращать контекст. Это эквивалент поворота дома, чтобы отвинтить лампочку.

Я вполне уверен, что это ваше решение. Так работает рисунок с CGContextRef.

Я был бы рад использовать CALayer, за исключением того, что CALayers, похоже, все ориентированы на растровую графику, и мне нужна векторная графика.

Вы пытались использовать CAShapeLayer?

+0

Ничего себе. Я забыл, что они существуют. Лемм посмотри на это. https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CAShapeLayer_class/Reference/Reference.html –

+0

Я, скорее всего, буду проверять комментарий CAShapeLayer как ответ позже завтра, после того как я получу шанс попробовать ее реализации. –

+0

CAShapeLayer сделал это. Я отправлю код позже, когда я его закончу. Благодаря! –

0

ОК, как и было обещано, вот код.

Во-первых, я использую 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 необходим, поскольку свойство преобразования слоя является трехмерным. Я использую M_PI_2, так как все преобразования в Radians (M_PI_2 - удобный макрос, который означает «90 °»), а -1 будет вращать вращение против часовой стрелки.

calculateRectForElement - это функция, которая определяет, где все находится. Он просто возвращает прямоугольник, который позиционирует элемент.

_top_left_element - свойство класса, которое является CALayer *.

Я сделал это, и ваш дядя Бьорн Стронгинтерам.

UPDATE:Я хотел бы добавить, что вам нужно, чтобы убедиться, что вы CGPathRelease пути этого слоя определяется в разгрузочном/самоуничтожении, или вы получите утечку.

Смежные вопросы