Подтвердить что ты не робот

IOS: Как мне поддерживать Retina Display с CGLayer?

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

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

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

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, так и устаревший.

Спасибо,

Куры

4b9b3361

Ответ 1

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

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

    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);
    
  • Затем вам нужно установить правильную шкалу для контекста вашего слоя:

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

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

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

Что это!

Ответ 2

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

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

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

С целью отсечения линий графика, превышающих край слоя, я решил использовать несколько CALayers.