Custom fonts not displaying correctly on iOS
I'm trying to get a set of Neo Sans Pro fonts working on the iPhone. I have four weights: Light, Regular, Medium, Bold as OTF files (NeoSansPro开发者_如何学Go-Light.otf, -Regular.otf etc). The files are included in the build, and registered in the info.plist.
Calling [UIFont fontNamesForFamilyName:@"Neo Sans Pro"]
returns an array with 4 entries e.g. "NeoSansPro-Light".
I can retrieve font objects for each of these strings using UIFont fontWithName:size:
.
However, when I draw text with them, the Light, Regular and Medium versions all draw exactly the same, and look like the Light version. The Bold version draws differently.
According to Font Book, each font file does contain different glyphs.
I'm completely stumped - any clues what I need to do?
[Added] Some more investigation:
NSArray *fonts = [UIFont fontNamesForFamilyName:@"Neo Sans Pro"];
for (NSString *fname in fonts) {
UIFont *font = [UIFont fontWithName:fname size:12.0];
NSLog(@"name: %@ font: %@", fname, font);
}
Running this code gives the following log output:
name: NeoSansPro-Light font: <UICFFont: 0x66304a0> font-family: "Neo Sans Pro"; font-weight: normal; font-style: normal; font-size: 12px
name: NeoSansPro-Regular font: <UICFFont: 0x66304a0> font-family: "Neo Sans Pro"; font-weight: normal; font-style: normal; font-size: 12px
name: NeoSansPro-Medium font: <UICFFont: 0x66304a0> font-family: "Neo Sans Pro"; font-weight: normal; font-style: normal; font-size: 12px
name: NeoSansPro-Bold font: <UICFFont: 0xaa06070> font-family: "Neo Sans Pro"; font-weight: bold; font-style: normal; font-size: 12px
So the three fonts that display the same really are the same. But there's four font weights and four fonts in the build.
Looks like this is the same problem as here: Including multiple fonts of the same family in an iPad application
It seems the iOS font architecture gets confused if there are multiple fonts in the same font family, and won't hand back the right font. The solution is to manually edit the font family information (using something like Font Forge to different values.
E.g. For the Neo Sans Pro Light font, set the Font family (in the PSNames and TTF Names) to "NSP Light". Do similarly for Neo Sans Pro Regular -> NSP Regular etc.
You can then refer to the font by the original name e.g. "NeoSansPro-Light"
Ugly, but it works.
Font forge looked a bit too much for me so I created a method that reads descriptions of the fonts in the fontsArray of a certain family and returns appropriate font.
- (UIFont*) getFontWithFamilyName:(NSString*)familyName bold:(Boolean)bold italic:(Boolean)italic size:(uint)size {
NSArray *fonts = [UIFont fontNamesForFamilyName:familyName];
for (NSString *fname in fonts) {
UIFont *font = [UIFont fontWithName:fname size:size];
Boolean isBold = [[font description] rangeOfString:@"bold"].location != NSNotFound;
Boolean isItalic = [[font description] rangeOfString:@"italic"].location != NSNotFound;
if (isBold == bold && isItalic == italic) {
return font;
}
}
//-- font was not found, provide system font bold or normal
if (bold) {
return [UIFont boldSystemFontOfSize:size];
} else {
return [UIFont systemFontOfSize:size];
}
}
I was using a Google font named Arvo. It had the following files:
- Arvo-Regular.ttf
- Arvo-Bold.ttf
- Arvo-BoldItalic.ttf
- Arvo-Italic.ttf
These names were added into my app's info.plist but for some reason, my app could only read the bold, bolditalic, and italic fonts. It couldn't read the regular font when i tried to load it. However, after printing out the font names, it came out that Arvo-Regular was recognized as Arvo in my app.
精彩评论