我可以在iPhone应用程序中嵌入自定义字体吗?

问题描述 投票:764回答:32

这个问题涉及iOS 3.2之前的版本。从3.2开始,使用下面的samvermette答案很容易实现这个功能,我已经改变了接受的答案(从命令到samvermette)以反映这一点。我不能赞同这两个答案(除了upvotes),但它们都很好。

我想有一个应用程序包括一个自定义字体用于渲染文本,加载它,然后使用它与标准的UIKit元素,如UILabel。这可能吗?

我在下面找到了链接:

但是这些要求我自己渲染每个字形,这有点太辛苦了,特别是对于多行文本。

我也发现帖子直截了当地表示这是不可能的,但没有理由,所以我正在寻找一个确定的答案。


编辑 - 失败的-[UIFont fontWithName:size:]实验

我下载了Harrowprint.tff(从here下载)并将其添加到我的Resources目录和项目中。然后我尝试了这段代码:

UIFont* font = [UIFont fontWithName:@"Harrowprint" size:20];

导致抛出异常。查看Finder中的TTF文件,确认字体名称为Harrowprint。


编辑 - 到目前为止已经有很多回复告诉我阅读关于X或Y的文档。我已经对所有这些进行了广泛的实验并且无处可去。在一个案例中,X结果仅与OS X相关,而不是在iPhone上。因此,我正在为这个问题设置一个赏金,我将奖励给第一个提供答案的人(仅使用文档化的API),他们会回答足够的信息以使其在设备上运行。在模拟器上工作也是一个奖励。


编辑 - 似乎赏金自动奖励得票最多的答案。有趣。实际上没有人提供解决问题的答案 - 涉及编码自己的UILabel子类的解决方案不支持自动换行,这对我来说是一个必不可少的功能 - 尽管我想我可以扩展它来做到这一点。

ios cocoa-touch fonts
32个回答
636
投票

iOS 3.2及更高版本支持此功能。直接来自iPhone OS 3.2 doc中的新功能:

自定义字体支持 想要使用自定义字体的应用程序现在可以在其应用程序包中包含这些字体,并通过在其Info.plist文件中包含UIAppFonts键来向系统注册这些字体。此键的值是一个字符串数组,用于标识应用程序包中的字体文件。当系统看到密钥时,它会加载指定的字体并使其可供应用程序使用。

Info.plist中设置字体后,您可以将自定义字体用作IB中的任何其他字体或以编程方式使用。

Apple Developer论坛上有一个持续的主题: https://devforums.apple.com/thread/37824(需要登录)

这是一个非常简单的3步教程,介绍如何实现这一目标(删除断开的链接)

  1. 使用Xcode作为资源将自定义字体文件添加到项目中
  2. Info.plist文件中添加一个名为UIAppFonts的密钥。
  3. 将此键设为数组
  4. 对于您拥有的每种字体,请输入字体文件的全名(包括扩展名)作为UIAppFonts数组的项目
  5. 保存Info.plist
  6. 现在在您的应用程序中,您只需调用[UIFont fontWithName:@"CustomFontName" size:12]即可获得与UILabels和UITextViews等一起使用的自定义字体...

另外:确保字体在Copy Bundle Resources中。


12
投票

这是一步一步说明如何做到这一点。无需额外的库或任何特殊编码。

http://shang-liang.com/blog/custom-fonts-in-ios4/

大多数情况下,问题在于字体而不是方法。最好的方法是使用肯定会起作用的字体,如verdana或geogia。然后更改为预期的字体。如果它不起作用,可能是字体名称不正确,或者字体不是格式良好的字体。


12
投票

在现有iOS应用程序上添加新字体非常容易。

你只需要添加字体,例如font.ttf进入资源文件夹。

打开你的应用程序info.plist。将新行添加为“由应用程序提供的字体”,并将字体名称键入为font.ttf。

设置字体时,请执行setFont:"corresponding Font Name"

你可以通过NSArray *check = [UIFont familyNames];检查你的字体是否被添加。

它返回应用程序支持的所有字体。


11
投票

我建议按照我最喜欢的简短教程之一:http://codewithchris.com/common-mistakes-with-adding-custom-fonts-to-your-ios-app/从中获取此信息。

第1步 - 将您的.ttf或.otf从Finder拖到您的项目中

注意 - 确保单击主应用程序目标上的“添加到目标”框

Drag font files into your project and click to add them to your target

如果您忘记单击将其添加到目标,然后单击项目层次结构中的字体文件,并在右侧面板上单击目标成员资格部分中的主应用程序目标

how to add fonts to app target if you forgot

要确保您的字体是应用程序目标的一部分,请确保它们显示在Build Phases中的Copy Bundle Resources中

how to check resources to see if fonts are part of app target

第2步 - 将字体文件名添加到Plist

转到信息部分中的自定义iOS目标属性,并为该部分中名为Fonts provided by application的项添加一个键(您应该看到它在您键入时作为选项出现,它将自己设置为数组。单击小箭头打开数组项并输入您添加的.ttf或.otf文件的名称,让您的应用知道这些是您想要的字体文件

注意 - 如果您的应用程序在此步骤后立即崩溃,请检查您在此处添加的项目的拼写

example plist with custom fonts added

第3步 - 找出字体的名称,以便您可以调用它们

通常,应用程序看到的字体名称与您认为基于该字体的文件名的字体名称不同,将其放在代码中并查看应用程序生成的日志,以查看代码中要调用的字体名称

迅速

for family: String in UIFont.familyNames(){
  print("\(family)")
  for names: String in UIFont.fontNamesForFamilyName(family){
      print("== \(names)")
  }
}

目标C.

for (NSString* family in [UIFont familyNames]){
    NSLog(@"%@", family);
    for (NSString* name in [UIFont fontNamesForFamilyName: family]){
        NSLog(@"  %@", name);
    }
}

您的日志应如下所示:

Example of searching log to find font names

第4步 - 使用步骤3中的名称使用新的自定义字体

迅速

 label.font = UIFont(name: "SourceSansPro-Regular", size: 18)

目标C.

 label.font = [UIFont fontWithName:@"SourceSansPro-Regular" size:18];

10
投票

在finder中找到TTF并“获取信息”。在“全名:”标题下,它给了我一个名字,然后我与fontWithName一起使用(我只是复制并粘贴了确切的名称,在这种情况下,不需要'.ttf'扩展名)。


8
投票

它尚未推出,但下一版本的cocos2d(2d游戏框架)将支持可变长度位图字体作为字符映射。

http://code.google.com/p/cocos2d-iphone/issues/detail?id=317

作者没有确定此版本的发布日期,但我确实看到一个帖子表明它将在下个月或两个月内发布。


8
投票

一个重要的注意事项:您应该使用与字体关联的“PostScript名称”,而不是其全名或系列名称。此名称通常可以与字体的常规名称不同。


6
投票

也许作者忘了给字体一个Mac FOND name

  1. FontForge中打开字体,然后转到Element> Font Info
  2. 有一个“Mac”选项,您可以在其中设置FOND名称。
  3. 在“文件”>“导出字体”下,您可以创建新的ttf

您也可以尝试在导出对话框中输入“Apple”选项。

免责声明:我不是iPhone开发人员!


6
投票

我一直在iOS 3.1.2上尝试这个页面上的各种建议,这些是我的结论:

即使使用FontForge设置FOND名称,只需将[UIFont fontWithName:size:]与Resources目录中的字体一起使用也行不通。

如果首先使用GSFontAddFromFile加载字体,[UIFont fontWithName:size:]将起作用。但是GSFontAddFromFile不是iOS 3.1.2的一部分,所以它必须按照@rpetrich的描述动态加载。


6
投票

按照这一步

1)在项目中复制字体

2)在源代码模式下打开你的.plist文件...(注意 - 不要打开info.plist

3)在此之前 - 右键单击​​你的字体并在fontforge或类似的编辑器中打开它,并在你的系统中打开install它应该是install

4)键入此

 <key>UIAppFonts</key>
<array>
    <string>MyriadPro.otf</string>
</array>

5)在class .m中输入此代码

 [lblPoints setFont:[UIFont fontWithName:@"Myriad Pro" size:15.0]];

这里lblPoints将会改变你的UILabel

完成!如果您的字体仍无效,请先检查字体兼容性


5
投票

查找ATSApplicationFontsPath

一个简单的plist条目,允许您将字体文件包含在应用程序资源文件夹中,并且它们在您的应用程序中“正常工作”。


297
投票

编辑:从iOS 3.2开始,此功能是内置的。如果您需要支持3.2之前的版本,您仍然可以使用此解决方案。

我创建了一个简单的模块,扩展UILabel并处理加载.ttf文件。我在Apache许可下发布了opensource,并把它放在github Here.

重要文件是FontLabel.hFontLabel.m

它使用了Genericrich's answer的一些代码。

浏览源Here.

要么

  • 将您的字体文件复制到资源中
  • 在您的Info.plist文件中添加一个名为UIAppFonts的密钥。 (“申请提供的字体)
  • 将此键设为数组
  • 对于您拥有的每种字体,请输入字体文件的全名(包括扩展名)作为UIAppFonts数组的项目
  • 保存Info.plist
  • 现在在您的应用程序中,您只需调用[UIFont fontWithName:@"CustomFontName" size:15]即可获得与UILabelsUITextViews等一起使用的自定义字体...

For More Information


5
投票

我已将此页面上的一些建议合并到iOS 5上适合我的内容中。

首先,您必须将自定义字体添加到项目中。然后,您需要遵循@iPhoneDev的建议并将字体添加到info.plist文件中。

完成后,这有效:

UIFont *yourCustomFont = [UIFont fontWithName:@"YOUR-CUSTOM-FONT-POSTSCRIPT-NAME" size:14.0];
[yourUILabel setFont:yourCustomFont];

但是,您需要知道字体的Postscript名称。只需按照@Daniel Wood的建议,在你使用FontBook时按下command-i。

然后,享受您的自定义字体。


5
投票

首先将.odt格式的字体添加到资源中,在这种情况下我们将使用DINEngschriftStd.otf,然后使用此代码将字体分配给标签

[theUILabel setFont:[UIFont fontWithName:@"DINEngschriftStd" size:21]];

要确保在项目中加载字体,请调用

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

在.plist上,您必须声明字体。只需添加“由应用程序提供的字体”记录,并添加一个带有字体名称的项目0字符串(DINEngschriftStd.otf)


5
投票

对于iOS 3.2及更高版本:使用上面几个提供的方法,它们是:

  1. 将您的字体文件(例如,Chalkduster.ttf)添加到XCode中项目的Resources文件夹中。
  2. 打开info.plist并添加一个名为UIAppFonts的新密钥。此键的类型应为数组。
  3. 将自定义字体名称添加到此数组,包括扩展名(“Chalkduster.ttf”)。
  4. 在您的应用程序中使用[UIFont fontWithName:@"Real Font Name" size:16]

但“真实字体名称”并不总是您在Fontbook中看到的那个。最好的方法是询问您的设备它看到的字体以及确切的名称。

我使用的是uifont-name-grabber:uifont-name-grabber

只需将您想要的字体放入xcode项目,将文件名添加到其plist,然后在您正在构建的设备上运行它,它将使用UIFont fontWithName:期望的名称通过电子邮件向您发送完整的字体列表。


5
投票

更好的解决方案是在你的Fonts provided by application文件中添加一个新属性“info.plist”。

然后,您可以像普通的UIFont一样使用自定义字体。


3
投票

从iOS 4.1开始,有一种使用自定义字体的新方法。它允许您动态加载字体,无论是应用程序附带的文件,下载的数据,还是您拥有的内容。它还允许您根据需要加载字体,而旧方法在应用程序启动时加载它们,如果您有许多字体,这可能需要很长时间。

新方法在ios-dynamic-font-loading中描述

您使用CTFontManagerRegisterGraphicsFont函数,为您的字体数据提供缓冲区。然后可以使用UIFont和Web视图,就像旧方法一样。以下是该链接的示例代码:

NSData *inData = /* your font-file data */;
CFErrorRef error;
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)inData);
CGFontRef font = CGFontCreateWithDataProvider(provider);
if (! CTFontManagerRegisterGraphicsFont(font, &error)) {
    CFStringRef errorDescription = CFErrorCopyDescription(error)
    NSLog(@"Failed to load font: %@", errorDescription);
    CFRelease(errorDescription);
}
CFRelease(font);
CFRelease(provider);

3
投票

Swift, code way: (works also with swift 2.0)

将所需的字体添加到项目中(就像添加图像一样,只需拖动到Xcode),确保它们针对您的项目 添加此方法并加载自定义字体(在appDelegate didFinishLaunchingWithOptions中推荐)

func loadFont(filePath: String) {

    let fontData = NSData(contentsOfFile: filePath)!

    let dataProvider = CGDataProviderCreateWithCFData(fontData)
    let cgFont = CGFontCreateWithDataProvider(dataProvider)!

    var error: Unmanaged<CFError>?
    if !CTFontManagerRegisterGraphicsFont(cgFont, &error) {
        let errorDescription: CFStringRef = CFErrorCopyDescription(error!.takeUnretainedValue())
        print("Unable to load font: %@", errorDescription, terminator: "")
    }

}

使用示例:

if let fontPath = NSBundle.mainBundle().pathForResource("My-Font", ofType: "ttf"){
      loadFont(fontPath)
}

使用字体:

UIFont(name: "My-Font", size: 16.5)

2
投票

您可以在资源文件夹中添加所需的“FONT”文件。然后转到Project Info.plist文件并使用KEY“应用程序提供的字体”并将值作为“FONT NAME”。

然后你可以调用方法[UIFont fontwithName:@"FONT NAME" size:12];


1
投票

我做了一切可能但新的字体没有出现所以我找到了解决方案:

当您拖动fot文件(otf或ttf)时,请忘记选中“添加到目标”下的复选框。

完成后,您的字体将出现,一切都会正常工作。


1
投票

虽然上面的一些答案是正确的,但我已经为仍然遇到字体问题的人写了详细的视觉教程。

上面的解决方案告诉您将字体添加到plist并使用

[self.labelOutlet setFont:[UIFont fontWithName:@"Sathu" size:10]];

是正确的。请现在使用任何其他hackish方式。如果您仍然遇到查找字体名称并添加它们的问题,这里是教程 -

Using custom fonts in ios application


1
投票

是,您可以在您的应用程序中使用自定义字体

一步一步跟着那里:

在支持文件中将自定义字体文件添加到项目中

在Info.plist文件中添加一个名为UIAppFonts的密钥。

将此键设为数组

对于您拥有的每种字体,请输入字体文件的全名(包括扩展名)作为UIAppFonts数组的项目

保存Info.plist现在在你的应用程序中你可以简单地调用[UIFont fontWithName:@“你的自定义字体名称”大小:20]来获取自己的UILabel使用的自定义字体,如果你没有得到正确的字体然后你双击在自定义字体上,仔细查看顶部字体名称是否正在复制并复制此字体,粘贴,这里[UIFont fontWithName:@“这里过去你的自定义字体名称”大小:20]

我希望你能得到正确答案


115
投票

有一种在iOS 4中使用自定义字体的简单方法。

  1. 将您的字体文件(例如,Chalkduster.ttf)添加到XCode中项目的Resources文件夹中。
  2. 打开info.plist并添加一个名为UIAppFonts的新密钥。此键的类型应为数组。
  3. 将自定义字体名称添加到此数组,包括扩展名(Chalkduster.ttf)。
  4. 现在,您可以在应用程序中使用[UIFont fontWithName:@"Chalkduster" size:16]

不幸的是,IB不允许使用自定义字体初始化标签。请参阅this question以解决此问题。我最喜欢的解决方案是使用自定义UILabel子类:

@implementation CustomFontLabel

- (id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super initWithCoder: decoder])
    {
        [self setFont: [UIFont fontWithName: @"Chalkduster" size: self.font.pointSize]];
    }
    return self;
}

@end

1
投票

是,您可以在您的应用程序中使用自定义字体

一步一步跟着那里:

  • 在支持文件中将自定义字体文件添加到项目中
  • 在您的Info.plist文件中添加一个名为UIAppFonts的密钥。
  • 将此键设为数组
  • 对于您拥有的每种字体,请输入字体文件的全名(包括扩展名)作为UIAppFonts数组的项目
  • 保存Info.plist现在在您的应用程序中,您可以简单地调用[UIFont fontWithName:@"your Custom font Name" size:20]来获取与UILabels一起使用的自定义字体

如果你没有得到正确的字体应用此后,你双击自定义字体,仔细看看顶部字体名称是来了并复制这个字体,粘贴,这里[UIFont fontWithName:@" here past your Custom font Name" size:20]我希望你会得到正确的答案


51
投票

在Info.plist中添加条目“由应用程序提供的字体”并将字体名称包括为字符串:

Fonts provided by application
           Item 0        myfontname.ttf
           Item 1        myfontname-bold.ttf
           ...

然后通过运行检查以确保包含您的字体:

for (NSString *familyName in [UIFont familyNames]) {
    for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {
         NSLog(@"%@", fontName);
    }
}

请注意,您的ttf文件名可能与设置标签字体时使用的名称不同(您可以使用上面的代码获取“fontWithName”参数):

[label setFont:[UIFont fontWithName:@"MyFontName-Regular" size:18]];

36
投票

编辑:从iOS3.2开始,此答案已不存在;使用UIAppFonts

我能够成功加载自定义UIFonts的唯一方法是通过私有GraphicsServices框架。

以下将在应用程序的主包中加载所有.ttf字体:

BOOL GSFontAddFromFile(const char * path);
NSUInteger loadFonts()
{
    NSUInteger newFontCount = 0;
    for (NSString *fontFile in [[NSBundle mainBundle] pathsForResourcesOfType:@"ttf" inDirectory:nil])
        newFontCount += GSFontAddFromFile([fontFile UTF8String]);
    return newFontCount;
}

加载字体后,可以像使用Apple提供的字体一样使用它们:

NSLog(@"Available Font Families: %@", [UIFont familyNames]);
[label setFont:[UIFont fontWithName:@"Consolas" size:20.0f]];

甚至可以在运行时加载GraphicsServices,以防API在将来消失:

#import <dlfcn.h>
NSUInteger loadFonts()
{
    NSUInteger newFontCount = 0;
    NSBundle *frameworkBundle = [NSBundle bundleWithIdentifier:@"com.apple.GraphicsServices"];
    const char *frameworkPath = [[frameworkBundle executablePath] UTF8String];
    if (frameworkPath) {
        void *graphicsServices = dlopen(frameworkPath, RTLD_NOLOAD | RTLD_LAZY);
        if (graphicsServices) {
            BOOL (*GSFontAddFromFile)(const char *) = dlsym(graphicsServices, "GSFontAddFromFile");
            if (GSFontAddFromFile)
                for (NSString *fontFile in [[NSBundle mainBundle] pathsForResourcesOfType:@"ttf" inDirectory:nil])
                    newFontCount += GSFontAddFromFile([fontFile UTF8String]);
        }
    }
    return newFontCount;
}

34
投票

使用iOS 8 +和Xcode 6 +,你可以很容易地做到这一点。以下是步骤:

1)将您的字体拖放到Xcode Supporting Files文件夹。不要忘记在添加到目标部分标记您的应用。从这一刻起,您可以在IB中使用此字体并从字体托盘中选择它。

2)要在您的设备中使用此字体,请打开info.plist并添加Fonts provided by application密钥。它将包含Item 0键,您必须添加您的字体名称作为值。字体名称可能与您的字体文件名不同。但首先,尝试在大多数情况下添加您的文件名。

如果没有,this article总是帮助我。

以下是本文代码的快速摘录,以帮助您找到您的字体名称。

func allFonts(){

   for family in UIFont.familyNames(){

       println(family)


       for name in UIFont.fontNamesForFamilyName(family.description)
       {
           println("  \(name)")
       }

   }

}

EDIT

我想提一下,您需要将字体文件添加到Target的Build Phases,Copy Bundle Resources。没有它,您将无法在设备上看到您的字体。它可能会导致意外行为。

例如,我遇到bug,当UITextField有自定义字体,但这个字体不在Copy Bundle Resources中。当我用这个viewcontroller塞入textfield时,在调用viewDidLoad函数之前有一个延迟大约4秒。解决字体问题消除了此延迟。所以,建议检查两次。 (rdar:// 20028250)顺便说一下,我无法重现这个bug,但我确定问题出现在字体上。


27
投票

我这样做了:

加载字体:

- (void)loadFont{
  // Get the path to our custom font and create a data provider.
  NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"mycustomfont" ofType:@"ttf"]; 
  CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);

  // Create the font with the data provider, then release the data provider.
  customFont = CGFontCreateWithDataProvider(fontDataProvider);
  CGDataProviderRelease(fontDataProvider); 
}

现在,在你的drawRect:,做这样的事情:

-(void)drawRect:(CGRect)rect{
    [super drawRect:rect];
    // Get the context.
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);
    // Set the customFont to be the font used to draw.
    CGContextSetFont(context, customFont);

    // Set how the context draws the font, what color, how big.
    CGContextSetTextDrawingMode(context, kCGTextFillStroke);
    CGContextSetFillColorWithColor(context, self.fontColor.CGColor);
    UIColor * strokeColor = [UIColor blackColor];
    CGContextSetStrokeColorWithColor(context, strokeColor.CGColor);
    CGContextSetFontSize(context, 48.0f);

    // Create an array of Glyph's the size of text that will be drawn.
    CGGlyph textToPrint[[self.theText length]];

    // Loop through the entire length of the text.
    for (int i = 0; i < [self.theText length]; ++i) {
        // Store each letter in a Glyph and subtract the MagicNumber to get appropriate value.
        textToPrint[i] = [[self.theText uppercaseString] characterAtIndex:i] + 3 - 32;
    }
    CGAffineTransform textTransform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
    CGContextSetTextMatrix(context, textTransform);
    CGContextShowGlyphsAtPoint(context, 20, 50, textToPrint, [self.theText length]);
}

基本上你必须在文本中做一些暴力循环并用魔术数字来寻找你的偏移量(在这里,请看我用29),但是它有效。

此外,您必须确保该字体是合法嵌入的。大多数都不是,并且有律师专门研究这类事情,所以要警告。


20
投票

是的,您可以包含自定义字体。请参阅有关UIFont的文档,特别是fontWithName:size:方法。

1)确保在资源文件夹中包含该字体。

2)字体的“名称”不一定是文件名。

3)确保您拥有使用该字体的合法权利。通过将其包含在您的应用中,您还可以分发它,并且您需要有权这样做。


20
投票

如果你正在使用xcode 4.3,你必须将font添加到Build Phase下的Copy Bundle Resources,根据https://stackoverflow.com/users/1292829/arne的帖子Custom Fonts Xcode 4.3。这对我有用,这里是我在我的应用程序中使用自定义字体的步骤:

  1. 将字体添加到项目中。我将OTF(或TTF)文件拖放到我创建的新组中并接受xcode选择的copying the files over to the project folder
  2. 创建UIAppFonts数组,并将字体列为数组中的项目。只是names,而不是延伸(例如“GothamBold”,“GothamBold-Italic”)。
  3. 点击屏幕左侧project name顶部的Project Navigator方式。
  4. 单击xcode主区域中显示的Build Phases选项卡。
  5. 展开“Copy Bundle Resources”部分,然后单击"+"添加字体。
  6. 从单击"+"时弹出的文件导航器中选择字体文件。
  7. add to the project所拥有的每种字体执行此操作。
© www.soinside.com 2019 - 2024. All rights reserved.