2012-01-23 3 views
1

Мне нужно нарисовать текст в CGContext и вы хотите использовать CATextLayer для установки текста. Может ли кто-нибудь дать мне несколько шагов относительно того, как это будет сделано. Я написал для него некоторый код, но не знаю его правильности (поскольку я новичок в iPhone Development).Использование CATextLayer с CGContext

Некоторые основные вопросы: 1. Как получить положение и размер текста для установки CATextLayer кадра 2. Текст как-то выходит перевернутым, который я исправляются CGAffineTransform, но его Hacky исправить, и я хочу знать фактическую причину, по которой текст выходит из инвертированного. 3. Мне также нужно установить ширину и цвет границы текста, для которых я использую NSAttributedString, но установка размера текста (увеличение или уменьшение) не отражается на экране.

EDIT 1:

Я обновил код, в соответствии с вашими рекомендациями, но текст не изменение размера даже после использования CTFontRef. Кроме того, на iPhone текст немного усекается сверху. Любая идея, что неправильно установлено? Когда я проверил значения, получаемые от getTypographicBounds, все они равны 0 (origin.x, origin.y, width и height).

Метод getTypographicBounds:

width = CTLineGetTypographicBounds(m_line, &ascent, &descent, &leading); 

// Return text bounds 
return CGRectMake(0, 0, width, ascent + descent); 

Измененный код:

CATextLayer* text  = [[CATextLayer alloc] init]; 
CGColorSpaceRef rgbColor = CGColorSpaceCreateDeviceRGB(); 
CGColorRef rgb   = CGColorCreate(rgbColor, m_fill_color); 
text.foregroundColor  = rgb; 
text.frame    = CGRectMake([self getTypographicBounds].origin.x, [self getTypographicBounds].origin.y, [self getTypographicBounds].size.width + 2*m_padding, [self getTypographicBounds].size.height + 2*m_padding); 
text.wrapped    = YES; 

    NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionary]; 

    CTFontRef aCFFont = CTFontCreateWithName ((CFStringRef)m_font_name, 30.0, NULL); 

    // Set a negative width so we get both stroke and fill to show 
    [stringAttributes setObject: (NSObject*)aCFFont forKey: (id)kCTFontNameAttribute]; 
    [stringAttributes setObject: [NSNumber numberWithFloat: -3 ] forKey: (id)kCTStrokeWidthAttributeName]; 
    [stringAttributes setObject: [UIColor whiteColor] forKey: (id)kCTStrokeColorAttributeName]; 

    NSAttributedString *stringToDraw = [[NSAttributedString alloc] initWithString:m_text 
                     attributes:stringAttributes]; 

    text.string = (NSString*)stringToDraw; 
    [text drawInContext:ctx]; 

EDIT 2: Пример вики использует CTLine, я использую CATextLayer. Причина :: CATextLayer позволяет мне изменять текст во время выполнения, чтобы показать китайский, японский, хинди, русский и все языки с разными сценариями. Кроме того, CATextLayer выглядит с большей ясностью, чем CoreText.

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что текст, отображаемый строкой [text drawInContext: ctx], усекается сверху. Я проверил размер фрейма и текста. Размер шрифта - 16 пикселей, а высота кадра - 17,768, поэтому я не знаю, почему это усекает.

// Ensure CTLine is up-to-date 
if (m_is_dirty) 
    [self recomputeLine]; 

// Get text metrics 
CGFloat width; 
CGFloat ascent; 
CGFloat descent; 
CGFloat leading; 

width = CTLineGetTypographicBounds(m_line, &ascent, &descent, &leading); 

// Position text so that top of text aligns with top of layer 
CGContextSetTextMatrix(ctx, CGAffineTransformIdentity); 

// Setup text drawing style 
CGContextSetRGBFillColor (ctx, m_fill_color [0], m_fill_color [1], m_fill_color [2], 1.0); 
CGContextSetRGBStrokeColor (ctx, m_stroke_color[0], m_stroke_color[1], m_stroke_color[2], 1.0); 
CGContextSetFont   (ctx, m_font  ); 
CGContextSetFontSize  (ctx, m_font_size ); 
CGContextSetLineWidth  (ctx, m_stroke_width); 

CATextLayer* text  = [[CATextLayer alloc] init]; 
CGColorSpaceRef rgbColor = CGColorSpaceCreateDeviceRGB(); 
CGColorRef rgb   = CGColorCreate(rgbColor, m_fill_color); 
text.foregroundColor  = rgb; 
text.fontSize = m_font_size; 
text.font = m_font; 
text.frame    = CGRectMake([self getTypographicBounds].origin.x, [self getTypographicBounds].origin.y, [self getTypographicBounds].size.width, [self getTypographicBounds].size.height); 
text.wrapped    = YES; 

NSMutableDictionary *stringAttributes = [NSMutableDictionary dictionary]; 


// Set a negative width so we get both stroke and fill to show 
[stringAttributes setObject: [UIFont fontWithName:m_font_name size:m_font_size] forKey: (id)kCTFontNameAttribute]; 
[stringAttributes setObject: [NSNumber numberWithFloat: -3 ] forKey: (id)kCTStrokeWidthAttributeName]; 
[stringAttributes setObject: [UIColor whiteColor] forKey: (id)kCTStrokeColorAttributeName]; 

NSAttributedString *stringToDraw = [[NSAttributedString alloc] initWithString:m_text 
                     attributes:stringAttributes]; 

text.string = (NSString*)stringToDraw;   
[text drawInContext:ctx]; 

Заранее спасибо

Ник

ответ

1

Именно из-за перевернутые координатами пространства, используемым для CGContexts. Полное объяснение (с диаграммами) см. here.

EDIT: Чтобы контролировать положение перевести контекст перед рисованием текст:

CGContextTranslateCTM(context, x, y); 

EDIT 2:

Похоже, вы должны использовать CTFontRef, а не UIFont. Например, см. here (см. Сообщение от Gordon Apple Wed Jun 23 10:40:23 2010).

EDIT 3:

, если только вы не должны использовать NSAttributedString, я бы рекомендовал использовать более простой NSString drawInRect: withFont: lineBreakMode: выравнивание: метод.Это создает CATextLayer для вас, но гораздо проще в использовании:

UIFont *font = [UIFont fontWithName:m_font_name size:30.f]; 
    [m_text drawInRect:text.frame withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft]; 

EDIT 4:

Попробуйте настроить словарь так:

CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)fontName, pointSize,NULL); 
    CGColorRef color = textColor.CGColor; 

    NSDictionary *attributesDict = [NSDictionary dictionaryWithObjectsAndKeys: 
            (__bridge id)ctFont, (id)kCTFontAttributeName, 
            color, (id)kCTForegroundColorAttributeName,nil]; 
+0

Круто. Теперь координатное пространство совершенное. Но все же не удалось изменить размер CATextLayer на основе атрибутов, установленных в NSAttributedString, или для установки свойства .fontSize для CATextLayer. – nikj

+0

Я отредактировал, чтобы показать, как управлять положением. Что касается размера, я не понимаю, что не так. Правильно ли шрифт? Какой размер он и какой размер вы пытаетесь сделать? –

+0

Эй, Хешуа, я обновил сообщение, пожалуйста, посмотрите. – nikj

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