自定义字体在iOS上显示不正确

9
我正在尝试在iPhone上使用一组Neo Sans Pro字体。我有四个字重:Light,Regular,Medium,Bold作为OTF文件(NeoSansPro-Light.otf,-Regular.otf等)。这些文件已包含在构建中,并在info.plist中注册。
调用[UIFont fontNamesForFamilyName:@"Neo Sans Pro"]将返回一个带有4个条目的数组,例如“NeoSansPro-Light”。
我可以使用UIFont fontWithName:size:为每个字符串检索字体对象。
然而,当我使用它们绘制文本时,Light,Regular和Medium版本都完全相同,并且看起来像Light版本。Bold版本则有所不同。
根据Font Book,每个字体文件确实包含不同的字形。
我完全被卡住了 - 有什么线索我需要做什么?
[添加] 进一步调查:
 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);
    }

运行此代码将生成以下日志输出:
 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

因此,显示相同的三种字体实际上是相同的。但是在构建中有四种字体重量和四种字体。


也尝试了使用TTF文件,但是发生了同样的情况。 - Malcolm Box
3个回答

12

看起来这个问题和这里的问题一样:在iPad应用程序中包含同一字体族的多种字体

似乎iOS字体架构会因为同一字体族中有多个字体而混淆,导致无法正确返回所需的字体。解决方法是手动编辑字体族信息(使用类似Font Forge之类的工具),将它们设置为不同的值。

例如,对于Neo Sans Pro Light字体,将字体系列(在PSNames和TTF Names中)设置为“NSP Light”。对于Neo Sans Pro Regular -> NSP Regular等字体也做同样处理。

然后,您可以通过原始名称引用字体,例如“NeoSansPro-Light”。

虽然有些不美观,但它能够解决问题。


3
几点澄清:在Font Forge中,这个功能可以在“元素”菜单下的“字体信息”中找到。另外,设置字体系列名并不影响实际效果,基本上你只需要将其从原来的系列名更改为独特的名称,这样iOS就能够通过该名称找到它,而不是通过其系列或字重。 - alalonde

0

我觉得 Font Forge 太过复杂,因此我创建了一个方法,该方法读取特定字体系列中 fontsArray 中字体的描述,并返回适当的字体。

- (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];
    }
}

你有试过安装同一字体家族的几种字体进行测试吗?我遇到的问题是 [UIFont fontWithName:] 不起作用,所以你的解决方案也不会起作用。 - Malcolm Box
显然,如果[UIFont fontWithName:]返回了某些内容,这将起作用。如果对您而言没有返回任何内容,我不确定问题是否在于您拥有同一字体系列的多个字体。多个字体应该返回多个数组条目。 - Lenka Pitonakova
1
我同意[UIFont fontWithName] 应该返回多个项,但由于它没有,所以这是苹果代码中的一个错误。因此需要采用上述解决方法。 - Malcolm Box

0

我正在使用名为Arvo的Google字体。它有以下文件:

  • Arvo-Regular.ttf
  • Arvo-Bold.ttf
  • Arvo-BoldItalic.ttf
  • Arvo-Italic.ttf

这些名称已添加到我的应用程序的info.plist中,但由于某种原因,当我尝试加载它时,我的应用程序只能读取粗体、粗斜体和斜体字体,无法读取常规字体。然而,在打印字体名称后,发现Arvo-Regular在我的应用程序中被识别为Arvo。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接