T#031 – Usiamo Font True Type personali nelle nostre applicazioni iPhone (ttf)
Salve a tutti, per chi non mi conoscesse (un po’ tutti credo
) sono l’autore di “Punti Patente Plus” rilasciata venerdì 9 aprile sull’AppStore e attualmente al primo posto tra le applicazioni più acquistate! Oggi vi parlerò di un argomento che può sembrare banale, ma, per quanto mi riguarda, mi ha richiesto non poche notti insonni.
Come sapete, è già possibile usare un Font True Type all’interno di iPhone, semplicemente specificando il suo FontFamily.
Esempio:
UILabel *hello_label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,200,30)]; [hello_label setFont:[UIFont fontWithName:@"Arial" size:30]];
Naturalmente se volete usare dei font non precaricati su iPhone, o addirittura avere la possibilitá di scaricarli da internet ed utilizzarli nell’applicativo onfly, questo codice non va bene, in quanto, dovreste prima registrarli.
Ecco una soluzione (non proprio indolore):
File: CustomFontBase.h
@interface CustomFontBase : UIView { NSMutableString *curText; UIColor *fontColor; UIColor *bgColor; int fontSize; NSString *fontName; NSString *fontExtension; float autoSizeWidth; int glyphOffset; BOOL isGlowing; UIColor *glowColor; } - (void)updateText:(NSString*)newText; - (void)initTextWithSize:(float)size color:(UIColor*)color bgColor:(UIColor*)bgColor; - (void)setGlow:(BOOL)glowing withColor:(UIColor*)color; - (void)autoSizeWidthNow; @property (nonatomic, retain) NSMutableString *curText; @end
File: CustomFontBase.m
#import "CustomFontBase.h" @implementation CustomFontBase @synthesize curText; - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // set defaults [self setBackgroundColor:[UIColor clearColor]]; bgColor = [UIColor clearColor]; [self setCurText: [[NSMutableString alloc] initWithString:@""] ]; fontColor = [UIColor whiteColor]; fontSize = 15; isGlowing = FALSE; [self setContentMode:UIViewContentModeTopLeft]; // make sure it doesn't scale/deform when setFrame is called } return self; } - (void)drawRect:(CGRect)rect { // get context and flip for normal coordinates CGContextRef context = UIGraphicsGetCurrentContext(); CGContextTranslateCTM ( context, 0, self.bounds.size.height ); CGContextScaleCTM ( context, 1.0, -1.0 ); // Get the path to our custom font and create a data provider. NSString *fontPath = [[NSBundle mainBundle] pathForResource:fontName ofType:fontExtension]; CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]); // Create the font with the data provider, then release the data provider. CGFontRef customFont = CGFontCreateWithDataProvider(fontDataProvider); CGDataProviderRelease(fontDataProvider); // Set the customFont to be the font used to draw. CGContextSetFont(context, customFont); // prepare characters for printing NSString *theText = [NSString stringWithString: curText]; int length = [theText length]; unichar chars[length]; CGGlyph glyphs[length]; [theText getCharacters:chars range:NSMakeRange(0, length)]; // draw bg if( bgColor != [UIColor clearColor] ) { CGRect bgRect = CGRectMake (0, 0, self.bounds.size.width, self.bounds.size.height); CGContextSetFillColorWithColor( context, bgColor.CGColor ); CGContextFillRect( context, bgRect ); } // Set how the context draws the font, what color, how big. CGContextSetTextDrawingMode(context, kCGTextFill); CGContextSetFillColorWithColor(context, fontColor.CGColor ); CGContextSetFontSize(context, fontSize); // set a glow? if( isGlowing ) { //CGContextSetShadow(context, CGSizeMake(0,0), 3 ); CGContextSetShadowWithColor( context, CGSizeMake(0,0), 3, glowColor.CGColor ); } // Loop through the entire length of the text. for (int i = 0; i < length; ++i) { // Store each letter in a Glyph and subtract the MagicNumber to get appropriate value. glyphs[i] = [theText characterAtIndex:i] + glyphOffset; } // draw the glyphs CGContextShowGlyphsAtPoint( context, 0, 0 + fontSize * .25, glyphs, length ); // hack the y-point to make sure it's not cut off below font baseline - this creates a perfect vertical fit // get width of text for autosizing the frame later (perhaps) CGPoint textEnd = CGContextGetTextPosition( context ); autoSizeWidth = textEnd.x; // clean up the font CGFontRelease( customFont ); } // call this after creating the LandscapeText object to set the styling - (void)initTextWithSize:(float)size color:(UIColor*)color bgColor:(UIColor*)txtBgColor { // store font properties fontColor = color; fontSize = size; bgColor = txtBgColor; // autoscale height to font size [self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, fontSize)]; } // set new text to display - (void)updateText:(NSString*)newText { [self setCurText: [NSString stringWithString:newText] ]; [self setNeedsDisplay]; } - (void)setGlow:(BOOL)glowing withColor:(UIColor*)color { glowColor = color; isGlowing = glowing; } - (void)autoSizeWidthNow { //printf( "autoSizeWidth = %f \n", autoSizeWidth ); [self setFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, autoSizeWidth, fontSize)]; } - (void)dealloc { [curText release]; [super dealloc]; } @end
Questa classe definisce una UIView con tutte le properties necessarie a gestire un font:
NSMutableString *curText; //testo da visualizzare UIColor *fontColor; //colore del testo UIColor *bgColor; //colore dello sfondo int fontSize; //grandezza del font NSString *fontName; //nome del font NSString *fontExtension; //estensione : nel nostro caso sarà sempre ttf (true type font) float autoSizeWidth; //se vogliamo che il testo si adatti alla lunghezza dello spazio disponibile int glyphOffset; //questa e le successive tre properties ci interessano per l'effetto glowing BOOL isGlowing; UIColor *glowColor;
Questa classe così definita ci servirà per usare un font true type, ma non deve essere usata direttamente, la estenderemo per ogni font nuovo che vorremo utilizzare.
File: CustomFontBase.h
#import "CustomFontBase.h" @interface CustomFontMyFont : CustomFontBase { } @end
File: CustomFontMyFont.m
#import "CustomFontMyFont.h" @implementation CustomFontMyFont - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // Initialization code fontName = @"NomeDelMioFontParticolare"; fontExtension = @"ttf"; glyphOffset = -29; } return self; } - (void)dealloc { [super dealloc]; } @end
L’idea è quella di avere una classe per ogni custom font che ci serve.
E ora vediamo l’utilizzo:
File: Test.m
#import "CustomFontMyFont.h" ........ CustomFontMyFont *myLabel = [[[CustomFontMyFont alloc] initWithFrame:CGRectMake(10, 50, 320, 200)] autorelease]; [myLabel initTextWithSize:[slider value] color:[UIColor whiteColor] bgColor:[UIColor clearColor] ]; [myLabel setGlow:YES withColor:[UIColor yellowColor]]; [myLabel updateText:@"http://www.sviluppoiphoneitalia.com"];
Spero sia tutto chiaro, se aveste dubbi o domande, lasciate un commento o, ancora meglio, utilizzate il nostro forum
Alla prossima..
..e mi raccomando.. date il vostro contributo acquistando la mia applicazione


















potresti pubblicare il codice sorgente con un font di esempio ?
Grazie