2010-02-23 1 views
10

Dans mon application, j'essaie de rendre le texte le long d'un chemin; c'est bien pour la plupart des personnages mais pas pour le japonais (ou quoi que ce soit d'autre que mac-romain). Il m'a été conseillé d'utiliser [NSString drawAtPoint] qui affiche les caractères corrects dans mon CATiledLayer; cependant, ils disparaissent après environ 5 secondes. En ce moment, je peux zoomer sur la couche et les mettre à l'échelle correctement, mais ils ne semblent pas être engagés dans CATiledLayer comme le reste du texte l'est habituellement.Utilisation de la méthode drawAtPoint de NSString à la place des problèmes CGContextShowGlyphsAtPoint

Avant de rendre, je vérifie la chaîne et décide si l'un d'entre eux ne sera pas rendu. Si je vais avoir des problèmes, j'utilise drawAtPoint à la place:

if (!isFullyDisplayable) 
{ 
    CGContextShowGlyphsAtPoint(context, pt.x, pt.y, realGlyph, 1); 
} 
else { 
    // fall back on less flexible font rendering for difficult characters 

    NSString *b = [gv text]; 
    NSString *c = [b substringWithRange:NSMakeRange(j,1)]; 

    [c drawAtPoint:pt withFont:[UIFont fontWithName:@"Helvetica-Bold" size:16.0]]; 


} 

Est-ce que quelqu'un a des pointeurs pour expliquer pourquoi le texte disparaît?

Dès que le drawAtPoint est utilisé ma sortie de débogage est inondé avec:

<Error>: CGContextGetShouldSmoothFonts: invalid context 
<Error>: CGContextSetFont: invalid context 
<Error>: CGContextSetTextMatrix: invalid context 
<Error>: CGContextSetFontSize: invalid context 
<Error>: CGContextSetTextPosition: invalid context 
<Error>: CGContextShowGlyphsWithAdvances: invalid context 

Je devine que c'est quelque chose à voir avec ma gestion de contexte, mais je suppose que si cela est dans le même placer comme j'utilise CGContextShowGlyphsAtPoint il devrait déjà avoir le bon contexte?

Répondre

17

répondre à ma propre question:

NSString drawAtPoint: withFont: utilise la pile de contexte, et d'où j'appelle cette méthode la pile est vide. Envelopper l'appel avec

UIGraphicsPushContext(context); and UIGraphicsPopContext(); 

fait l'affaire.

+1

Vous devriez mentionner que cela ne fonctionne que sur iOS 4.0 et versions ultérieures. Les extensions graphiques UIKit ne sont pas adaptées aux threads dans les anciens logiciels. – Split

1

Pour être complet, voici le code nécessaire pour Cocoa. Fonctionne également avec .drawInRect ...

CGContextSaveGState(context) 
let old_nsctx = NSGraphicsContext.currentContext() // in case there was one 
// force "my" context... 
NSGraphicsContext.setCurrentContext(NSGraphicsContext(CGContext: context, flipped: true)) 

// Do any rotations, translations, etc. here 
str.drawAtPoint(cgPt, withAttributes: attributes) 

NSGraphicsContext.setCurrentContext(old_nsctx)// clean up for others 
CGContextRestoreGState(context) 

Cela est surtout pas nécessaire, comme le dit @davbryn, comme normalement il existe déjà un « travail » contexte sur la pile qui est la même (vous espérez!) comme votre contexte, cependant, comme il le fait remarquer, parfois il n'y en a pas. J'ai découvert ce problème en particulier avec drawMapRect: de MapKit, qui ne montrerait tout simplement pas le texte sans définir explicitement le contexte.

Questions connexes