iphone - 一个iphone应用程序可以嵌入自定义字体?

  显示原文与译文双语对照的内容

这个问题涉及 iOS pre-3.2. 到 3.2,这个功能很容易使用下面的samvermette回答,我已经改变了接受的答案( 从CommandA到 samvermette ) 来反映这个问题。 我不能同时给两个答案( 除了 uproots ),但它们都很好。

我想让一个应用包括一个自定义字体,用于呈现文本,加载它,然后使用标准的UIKit元素,比如 UILabel 。 这可能吗?

我找到了这些链接:

但这需要我自己渲染每个字形,这有点太像硬的工作,尤其对于multi-line文本。

我也发现了一些帖子,指出这是不可能的,但没有理由,所以我寻找一个明确的答案。


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

我下载了 Harrowprint.tff ( 从下载的 web ) 并将它的添加到我的资源目录和项目中。 然后我尝试了以下代码:


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

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


编辑- 目前为止有很多回复,这让我可以阅读关于X 或者Y的文档。 我已经对所有这些都做了大量的实验,而且一无所获。 在一个例子中,OS X 只与相关,而不是在iPhone上。 在device,因此对于这个问题,我在设置一个bounty和我会批出bounty到第一人谁提供一个答案( 只使用文档化的api ) 谁足够的信息进行响应来获得这个工作后。 在模拟器上工作也是奖金。


编辑- 似乎奖励auto-awards的票数最高。 有趣的是,没有人真正提供了解决问题的答案。这个解决方案涉及到编码你自己的UILabel子类的解决方案,但我想我可以扩展它。

时间:

iOS 3.2和更高版本支持这里操作。 在iPhone操作系统 3.2 doc,一直到海岸线 new:是什么

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

Info.plist 中设置字体后,你可以使用自定义字体作为IB中的任何其他字体。

在苹果开发者论坛上有一个持续的线索:
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] 要使用的自定义字体以小时为你 UILabelsUITextViews,等等 。

同时:确保字体在你的复制包资源中。

有一个简单的方法,可以使用自定义字体在的iOS 4

  1. 将你的字体文件( 例如 Chalkduster.ttf ) 添加到项目中的资源文件夹。
  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

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

收费:这里答案因 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-provided字体一样使用它们:


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

我已经这样做了:

加载字体:


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

在字体,但它works,基本上你必须做一些暴力对文本和有关与魔术数字结合在一起你的偏移futzing执行循环

此外,你必须确保字体合法可以嵌入。 大多数人都不存在,并且有律师擅长这种事情,所以被警告。

如果你使用的是 Xcode 4.3,则必须将字体添加到Copy复制包资源under下的构建阶段,根据线程中的http://stackoverflow.com/users/1292829/arne自定义字体 Xcode 4.3 。 这适用于我,这是我在应用程序中使用自定义字体的步骤:

  1. 将字体添加到项目中。 我将传递函数( 或者 TTF ) 文件拖放到一个新的组,我创建并接受了将文件复制到项目文件夹的xcode 。
  2. 创建UIAppFonts数组,其中列出的字体作为数组中的项目。 只是名称,而不是扩展名( 例如。 "gothambold","gothambold-italic") 。
  3. 单击屏幕左侧项目导航器顶部的项目名称方式。
  4. 单击出现在xcode主区域的构建阶段选项卡。
  5. 展开"复制包资源"部分并单击"+"添加字体。
  6. 选择单击"+"时打开的文件导航器中的字体文件。
  7. 对你要添加到项目中的每种字体进行这里操作。

使用新的Xcode 6,你可以轻松地做到这一点。 以下是步骤:

1 ) 拖放你的字体到支持文件文件夹的Xcode 。 别忘了在"添加到目标"部分标记你的应用程序。 从这一刻起,你可以在IB中使用该字体,并从字体托盘中选择它。

enter image description here

2 ) 要使这里字体在你的设备中可用,请打开 info.plist 并添加 Fonts provided by application 键。它将包含项 0项,你必须将你的字体名称添加为。 字体名称因字体文件名不同而异。 但是首先,尝试在大多数情况下添加你的文件名。

enter image description here

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

下面是本文代码的Swift Fragment,帮助你查找字体名称。


func allFonts(){

 for family in UIFont.familyNames(){

 println(family)


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

 }

}

编辑

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

例如我遇到一个 Bug,当它有自定义字体时,但这些字体不在复制包资源中。 当我使用此文本字段连接到视图控制器时,在调用viewDidLoad函数之前,大约有 4秒的延迟。 解决字体故障消除这里延迟。 所以,建议你检查两次。 (rdar://20028250)

是,你可以包括自定义字体。 请参考UIFont上的文档,特别是 fontWithName:size: 方法。

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

2 ) 字体的"姓名"不一定是文件名。

请确认你有使用该字体的合法权限。 通过将它包括在你的应用程序中,你也可以分发它,你需要有这样做的权利。

...