iOS: как мне поддержать Retina Display с помощью CGLayer? - PullRequest
19 голосов
/ 18 июля 2011

Я рисую график на CALayer в методе его делегата drawLayer:inContext:.

Теперь я хочу поддержать Retina Display, так как график выглядит размытым на последних устройствах.

Для частей, которые я рисую непосредственно в графическом контексте, передаваемом CALayer, я мог бы красиво рисовать в высоком разрешении, устанавливая свойство contentScale CALayer следующим образом.

if ([myLayer respondsToSelector:@selector(setContentsScale:)]) {
    myLayer.contentsScale = [[UIScreen mainScreen] scale];
}

Но для частей, которые я использую CGLayer,все еще нарисовано размытым.

Как рисовать на CGLayer в высоком разрешении для поддержки Retina Display?

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

Я получаю CGLayer на CGLayerCreateWithContex с графическим контекстом, переданным из CALayer, и рисую его контекст, используя такие функции CG, как CGContextFillPath или CGContextAddLineToPoint.

Мне нужно поддерживать iOS 4.x и iOS 3.1.3, Retina и устаревший дисплей.

Спасибо,

Kura

Ответы [ 2 ]

28 голосов
/ 05 января 2012

Вот как правильно нарисовать CGLayer для всех разрешений.

  1. При первом создании слоя необходимо рассчитать правильные границы, умножив размеры на масштаб:

    int width = 25; 
    int height = 25;
    float scale = [self contentScaleFactor];
    CGRect bounds = CGRectMake(0, 0, width * scale, height * scale);
    CGLayer layer = CGLayerCreateWithContext(context, bounds.size, NULL);
    CGContextRef layerContext = CGLayerGetContext(layer);
    
  2. Затем необходимо установить правильный масштаб для контекста слоя:

    CGContextScaleCTM(layerContext, scale, scale);
    
  3. Если текущее устройство имеет сетчатку,все рисунки, сделанные на слое, теперь будут отрисовываться в два раза больше.

  4. Когда вы наконец отрисовываете содержимое своего слоя, убедитесь, что вы используете CGContextDrawLayerInRect и предоставили немасштабированный CGRect:

    CGRect bounds = CGRectMake(0, 0, width, height);
    CGContextDrawLayerInRect(context, bounds, layerContext);
    

Вот и все!

1 голос
/ 20 июля 2011

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

Я нашел похожий вопрос здесь и обнаружил, что в моем случае нет смысла использовать CGLayer.

Я использовал CGLayer из-за примера программы Apple «Использование нескольких объектов CGLayer для рисования флага» , найденной в КварцеРуководство по 2D программированию.В этом примере он создает один CGLayer для звезды и использует его несколько раз, чтобы нарисовать 50 звезд.Я думал, что это было связано с производительностью, но я не видел никакой разницы в производительности.

В целях обрезки линий графика, выходящих за край слоя, я решил использовать несколько слоев CALay.

...