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

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

240035 次浏览

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

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

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

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

我已经这样做了:

加载字体:

- (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),但它有效。

此外,你必须确保字体在法律上是可嵌入的。大多数不是,有律师专门从事这类事情,所以要注意。

向上看ATSApplicationFontsPath

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

它还没有出来,但下一个版本的cocos2d(2d游戏框架)将支持可变长度的位图字体作为角色地图。

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

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

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

我创建了一个扩展UILabel并处理加载. ttf文件的简单模块。我在Apache许可下开源发布并将其放在github这里。

重要的文件是FontLabel.hFontLabel.m

它使用了普赖恩里奇的回答中的一些代码。

浏览源代码这里。

  • 将字体文件复制到资源中

  • 向名为UIAppFonts的Info.plist文件添加一个键。(“应用程序提供的字体)

  • 将此键设为数组

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

  • 保存Info.plist

  • 现在在您的应用程序中,您可以简单地调用[UIFont fontWithName:@"CustomFontName" size:15]来获取要与UILabelsUITextViews等一起使用的自定义字体。

更多信息

编辑:此答案自iOS3.2起失效;使用UIAppFonts

我能够成功加载自定义UIFont的唯一方法是通过私有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;}

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

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

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

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

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

简单地将[UIFont fontWithName:size:]与Resources目录中的字体一起使用将不起作用,即使使用FontForge设置了FOND名称。

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

iOS3.2及更高版本支持此功能。直接来自什么是新的iPhoneOS 3.2文档:

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

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

苹果开发者论坛上有一个正在进行的线程:
https://devforums.apple.com/thread/37824(需要登录)

这里有一个优秀而简单的3步教程,说明如何实现这一点(断开的链接已删除)

  1. 使用Xcode作为资源将您的自定义字体文件添加到您的项目中
  2. 将密钥添加到名为UIAppFontsInfo.plist文件中。
  3. 将此键设为数组
  4. 对于您拥有的每种字体,输入字体文件的全名(包括扩展名)作为UIAppFonts数组的项目
  5. 保存Info.plist
  6. 现在在您的应用程序中,您可以简单地调用[UIFont fontWithName:@"CustomFontName" size:12]来获取要与UILabelsUITextView消息列表等一起使用的自定义字体。

另外:确保字体在复制捆绑资源中。

有一种简单的方法可以在iOS4中使用自定义字体。

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

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

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

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

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

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

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

这是一步一步的说明。不需要额外的库或任何特殊的编码。

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

大多数情况下,问题出在字体而不是方法上。最好的方法是使用一种肯定会起作用的字体,比如verdana或Geogia。然后更改为预期的字体。如果它不起作用,可能是字体名称不对,或者字体格式不好。

iOS3.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发布在:用户名获取器

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

如果您使用的是xcode 4.3,您必须将font添加到Copy Bundle Resources下的Build Phase中,根据线程中的https://stackoverflow.com/users/1292829/arne自定义字体Xcode 4.3。这对我很有效,以下是我为在我的应用程序中使用自定义字体所采取的步骤:

  1. 将字体添加到您的项目中。我将OTF(或TTF)文件拖放到我创建的新组中,并接受xcode选择的copying the files over to the project folder
  2. 创建UIAppFonts数组,将您的字体列为数组中的项目。只有names,而不是扩展名(例如“GothamBold”、“GothamBold-Italic”)。
  3. 单击屏幕左侧Project Navigator顶部的project name方式。
  4. 单击出现在xcode主区域中的Build Phases选项卡。
  5. 展开“Copy Bundle Resources”部分并单击"+"添加字体。
  6. 从单击"+"时弹出的文件导航器中选择字体文件。
  7. 对你必须add to the project的每个字体都这样做。

在您现有的iOSApp上添加新字体非常容易。

您只需要添加字体,例如font.ttf到您的资源文件夹。

打开您的应用程序info.plist。添加一个新行作为“应用程序提供的字体”并键入字体名称font.ttf.

当设置字体时,做setFont:"corresponding Font Name"

您可以检查您的字体是否由NSArray *check = [UIFont familyNames];添加。

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

我已经将本页上的一些建议合并到iOS5对我有用的东西中。

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

在你这样做之后,这是有效的:

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

但是,您需要知道字体的PostScript名称。只需按照@Daniel Wood的建议并在FontBook中按命令-i即可。

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

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

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

要确保您的字体已加载到项目中,只需调用

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

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

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

Fonts provided by applicationItem 0        myfontname.ttfItem 1        myfontname-bold.ttf...

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

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

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

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

您可以在资源文件夹中添加所需的“字体”文件。然后转到项目Info.plist文件并使用关键字“应用程序提供的字体”和值作为“字体名称”。

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

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

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

这样做后,你的字体就会出现,一切都会正常工作。

按照这一步

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

这里lblPoint将从您的UILabel开始更改

完成!!如果您的字体仍然不起作用,请先检查您的字体兼容性

有一种使用自定义字体的新方法,从iOS4.1开始。它允许您动态加载字体,无论是来自应用程序包含的文件、下载的数据还是您拥有的文件。它还允许您根据需要加载字体,而旧方法在应用程序启动时全部加载它们,如果您有许多字体,这可能会花费太长时间。

新方法在ios-动态-字体-加载中描述

您使用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);

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

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

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

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

在iOS应用程序中使用自定义字体

作为增强@bdev的回答,这里是一个更新版本,仅列出自定义字体。

第1步:使用@bdev的答案找出所有系统字体并保存到文件中。

将以下代码放在第一个View Controller的-(void)viewDidLoad中,在[super viewDidLoad]之后(或在App委托中):

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);NSMutableArray *system_fonts = [NSMutableArray array];for (NSString *familyName in [UIFont familyNames]) {for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {[system_fonts addObject:fontName];}}if([paths count] > 0) {[system_fonts writeToFile:[[paths objectAtIndex:0]stringByAppendingPathComponent:@"array.out"] atomically:YES];}

运行应用程序一次。之后停止它。

第2步:将自定义字体添加到项目

使用已接受答案中显示的方法,添加您的自定义字体(请记住更新.plist并通过选中Add To Target添加要构建的字体文件。

第3步:将系统字体与当前字体列表进行比较

将步骤1中的代码替换为:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);NSMutableArray *system_fonts = [NSMutableArray arrayWithContentsOfFile:[[paths objectAtIndex:0]stringByAppendingPathComponent:@"array.out"]];
for (NSString *familyName in [UIFont familyNames]) {for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName]) {if (![system_fonts containsObject:fontName]) {NSLog(@"%@", fontName);}}}

运行应用程序,将显示您添加的自定义字体列表。

这适用于iOS3.2到iOS6(未来的版本可能工作正常)。也适用于.ttc.ttf

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

一步一步地跟随在那里:

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

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

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

一步一步地跟随在那里:

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

将密钥添加到名为UIAppFonts的Info.plist文件中。

将此键设为数组

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

保存Info.plist现在在您的应用程序中,您可以简单地调用[UIFont fontWith Name:@"your Custom字体名称"size: 20]来获取要与您的UILabels一起使用的自定义字体应用后,如果你没有得到正确的字体,然后你双击自定义字体,并仔细查看顶部侧字体名称是即将和复制此字体,粘贴,在这里[UIFont fontWith Name:@"这里过去你的自定义字体名称"size: 20]

我希望你能得到正确的答案

使用iOS 8+和Xcode 6+,您可以轻松完成此操作。以下是步骤:

1)将您的字体拖放到Xcode支持文件文件夹。不要忘记在添加到目标部分标记您的应用程序。从现在开始,您可以在IB中使用此字体并从字体托盘中选择它。

输入图片描述

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

输入图片描述

如果不是,这篇文章总是帮助我。

这是本文中的代码片段,可帮助您找到字体名称。

func allFonts(){
for family in UIFont.familyNames(){
println(family)

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

编辑

我想提一下,您需要将字体文件添加到目标的构建阶段复制捆绑包资源。没有它,您将无法在设备上看到您的字体。这可能会导致意外行为。

例如,我遇到一个bug,当UITextField有自定义字体时,但这种字体不在复制捆绑包资源中。当我用这个textfield转到viewcontroller时,在调用viewDidLoad函数之前有大约4秒的延迟。解决字体问题消除了这个延迟。所以,建议检查两次。(rdar://20028250)顺便说一句,我无法复制bug,但我确定问题出在字体上。

我会推荐以下我最喜欢的一个简短教程:http://codewithchris.com/common-mistakes-with-adding-custom-fonts-to-your-ios-app/,这些信息来自哪里。

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

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

将字体文件拖到您的项目中并单击以将它们添加到您的目标

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

如果你忘记了如何将字体添加到应用程序目标

要确保您的字体是您的应用程序目标的一部分,请确保它们显示在构建阶段中的复制捆绑包资源

如何检查资源以查看字体是否是应用目标的一部分

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

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

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

添加自定义字体的示例plist

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

很多时候你的应用程序看到的字体名称与你认为它是基于该字体的文件名的不同,把它放在你的代码中,并查看你的应用程序的日志,看看在你的代码中调用什么字体名称

Swift

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);}}

你的日志应该看起来像这样:

搜索日志以查找字体名称的示例

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

Swift

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

目标c

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

Swift,代码方式:(也适用于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)

正如前面所有的答案所指出的,这是非常可能的,并且在较新的iOS版本中非常容易。

我知道这不是一个技术上的答案,但由于很多人确实犯了错误(因此实际上违反了许可证,如果你被起诉,可能会花费你很多钱),让我在这里加强一个警告:在iOS(或任何其他类型)应用程序中嵌入自定义字体基本上是重新分配字体。大多数商业字体许可证都会进行禁止重新分发,所以请确保您根据许可证行事。