如何检查iOS版本中是否可用某种字体?

60
我目前正在开发一个使用“ChalkboardSE-Regular”字体的应用程序,我的部署目标是4.0+。该字体在4.1中不可用,但在4.3中受支持。如何最好地检查字体是否存在,如果不存在,则在iOS<4.1版本上使用另一个支持的字体。[UIFont familyName]返回这些字体的列表,“Chalkboard SE”。谢谢!
15个回答

114

[UIFont familyName]从iPhone OS 2.0开始就得到支持(在2.0之前,iPhone或iPod touch上不允许第三方应用程序),因此我建议使用它来检查当前设备上是否存在字体系列,如果不存在,则使用适合当前版本iOS的备用字体。以下是John Gruber在2007年发布的iPhone字体列表(与当时的Mac OS X中的字体进行对比)。我没有检查它们全部,但我检查了一些iOS字体,它们仍然存在于iOS 5中:

这里是一个使用[UIFont familyName]的示例:

NSLog (@"Font families: %@", [UIFont familyNames]);

这将产生如下列表:

字体系列:( Thonburi, "Snell Roundhand", "Academy Engraved LET",...等等。

一旦您知道字体系列名称,您可以使用UIFont类方法fontNamesForFamilyName获取该系列中所有字体的名称NSArray。例如:

NSLog (@"Courier New family fonts: %@", [UIFont fontNamesForFamilyName:@"Courier New"]);

这将产生一个类似这样的列表:

Courier New字体族:( CourierNewPSMT, "CourierNewPS-BoldMT", "CourierNewPS-BoldItalicMT", "CourierNewPS-ItalicMT" )

下面的示例代码打印出当前设备上每个族中每个字体的列表:

NSArray *fontFamilies = [UIFont familyNames];

for (int i = 0; i < [fontFamilies count]; i++)
{
    NSString *fontFamily = [fontFamilies objectAtIndex:i];
    NSArray *fontNames = [UIFont fontNamesForFamilyName:[fontFamilies objectAtIndex:i]];
    NSLog (@"%@: %@", fontFamily, fontNames);
}

想要了解更多信息,请查看iOS开发者参考文档中UIFont类方法familyNamesfontNamesForFamilyName:


1
我还编写了一个应用程序,以示例文本的形式将它们全部转储出来。你可能只想从这里开始 https://github.com/palmerc/iOS5Fonts - Cameron Lowell Palmer
这段程序代码在 Swift 中也是一样的: for family:String in (UIFont.familyNames() as String[]) { println(family) for name:String in (UIFont.fontNamesForFamilyName(family) as String[]) { println("\t \(name)") } } - magegu

59

如果您使用Swift,可以打印所有字体(参见下文)。您还可以检查字体是否存在。

for family in UIFont.familyNames {
    print("\(family)")

    for name in UIFont.fontNames(forFamilyName: family) {
        print("   \(name)")
    }
}

16

Swift 5.x

忘记那些for循环吧,这是查看iOS支持的字体最简单的方法。

只需在Playground中运行以下任何一个。


仅限家族名称

输入

dump(UIFont.familyNames)

输出

 75 elements
  - "Copperplate"
  - "Heiti SC"
  - "Kohinoor Telugu"
  ...

仅字体名称

输入


dump(UIFont.familyNames.compactMap { UIFont.fontNames(forFamilyName: $0) })    

输出

 248 elements
  - "Copperplate-Light"
  - "Copperplate"
  - "Copperplate-Bold"
  ...

指定字体族名称的字体名称

输入

dump(UIFont.fontNames(forFamilyName: "Helvetica Neue"))

输出

 14 elements
  - "HelveticaNeue-Italic"
  - "HelveticaNeue-Bold"
  - "HelveticaNeue-UltraLight"
  - "HelveticaNeue-CondensedBlack"
  ...

1
非常有帮助!谢谢! - m_katsifarakis
1
我怎么之前不知道 dump 这个东西?很好用。 - Shayne
1
对于上面仅针对字体名称的示例,compactMap方法生成一个由字体名称分组的二维字符串数组。如果您需要将所有字体名称放在单个字符串数组中,请改用flatMap而不是compactMap。 - BP.

14

这种字体在4.1版本中不可用,但在4.3版本中支持。如何最好地检查该字体是否存在?

通常通过UIFont* f = [UIFont fontWithName:... size:...];的方式来请求该字体。如果该字体不可用,则结果(f)将为nil。

(确保字体可用的一种方法是将其包含在应用程序bundle中...)


请问您能详细说明一下吗?(“将其包括在应用程序包中”)您会如何操作,从哪里复制它,这样做不会侵犯(十几个)法律/版权等问题吗?我之所以问,是因为在iOS6中,MarkerFelt字体存在一个“错误”。希腊字母S(最终sigma)的显示方式像小写的ζ...我能否在我的应用程序中包含iOS5的MarkerFelt字体?我该怎么做? - Gik
字体就像项目中的其他资源一样。如果它被包含在“复制捆绑资源”构建阶段中,它会被复制到您的捆绑包中。请参考我的书:http://www.apeth.com/iOSBook/ch06.html#_the_target。请注意,您需要在Info.plist中设置UIAppFonts键,以通知运行时您的捆绑包中有一个需要获取的字体。 - matt

4

对于iOS9 / Swift 2.0,以上方法都不适用了,因为语法有所改变。我个人更喜欢使用扩展(我选择为UIFont创建一个扩展,因为它最适合,并修改了@API答案,因为这是最好的方法):

extension UIFont {

    static func availableFonts() {

        // Get all fonts families
        for family in UIFont.familyNames() {
            NSLog("\(family)")

            // Show all fonts for any given family
            for name in UIFont.fontNamesForFamilyName(family) {
                NSLog("   \(name)")
            }
        }
    }
} 

现在您可以直接调用:
UIFont.availableFonts()

它会将所有字体以某种形式告诉你。

: Bangla Sangam MN
:    BanglaSangamMN-Bold
:    BanglaSangamMN
: Zapfino
:    Zapfino

希望这有所帮助!

2

相较于编写一行代码,您可以打开http://iosfonts.com并根据您的iOS版本支持检查可用性。您还可以了解它的外观。

http://iosfonts.com预览功能


2

Swift版本:

UIFont.familyNames().sort( { $0 < $1 } ).forEach({ print("\($0)"); UIFont.fontNamesForFamilyName("\($0)").sort( { $0 < $1 } ).forEach({ print("     \($0)") }) })

2

以下是我在Objective-C中查找字体是否可用的方法:

NSFont *font = [NSFont fontWithName:@"thefont" size:25.0];
if (font==nil) {
    // thefont is available
} else {
    // thefont is not available
}

我非常确定,如果字体为 nil,则该字体不可用 =p - highboi

1
尝试使用该字体名称进行初始化,如果为nil则执行其他操作。Swift代码:

if let font = UIFont(name: name, size: size) { // 正常 } else { // 不正常 }


1
我发现使用SwiftUI预览,你可以制作一个应用程序,在预览模拟器中展示每种字体的外观。
struct TitleViewModifier_Previews:
    PreviewProvider {
    
    static var previews: some View {

        List{
            ForEach(UIFont.familyNames.sorted(),id: \.self){ family in
                ForEach(UIFont.fontNames(forFamilyName: family), id: \.self){ eachFont in
                    Text(eachFont)
                        .font(.custom(eachFont, size: 22))
                }
            }
        }
    }
}

这是我的预览效果 按下播放按钮使列表变得交互式和可滚动 enter image description here

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