"HelveticaNeue-Italic" 在 iOS 7.0.3 上发生了什么?

101

我刚把iPod Touch升级到iOS 7.0.3,但"HelveticaNeue-Italic"似乎消失了。当我在手机上查询时:

[UIFont fontNamesForFamilyName:@"Helvetica Neue"]

我得到了以下字体名称(13个):

HelveticaNeue-BoldItalic,
HelveticaNeue-Light,
HelveticaNeue-UltraLightItalic,
HelveticaNeue-CondensedBold,
HelveticaNeue-MediumItalic,
HelveticaNeue-Thin,
HelveticaNeue-Medium,
HelveticaNeue-ThinItalic,
HelveticaNeue-LightItalic,
HelveticaNeue-UltraLight,
HelveticaNeue-Bold,
HelveticaNeue,
HelveticaNeue-CondensedBlack

当我在模拟器中运行相同的查询时,我得到了(14):

HelveticaNeue-BoldItalic,
HelveticaNeue-Light,
**HelveticaNeue-Italic,**
HelveticaNeue-UltraLightItalic,
HelveticaNeue-CondensedBold,
HelveticaNeue-MediumItalic,
HelveticaNeue-Thin,
HelveticaNeue-Medium,
HelveticaNeue-Thin_Italic,
HelveticaNeue-LightItalic,
HelveticaNeue-UltraLight,
HelveticaNeue-Bold,
HelveticaNeue,
HelveticaNeue-CondensedBlack

还有人看到这个吗?

---- 新信息 ----

我回到了 WWDC 2013 视频“Using Font with Text Kit”,有趣的部分从12:22 开始。演讲者谈到了 OS X 中的“MetaFonts”作为一个例子。他说,在像下面这样的调用下使用的字体:

+ (NSFont *)messageFontOfSize:(CGFloat)fontSize

不能保证在不同版本或不同用途中返回相同的底层字体。他举的例子是Lucida Grande。他似乎并没有说使用“HelveticaNeue-Italic”可能会在不同版本中消失。

因此,我在iOS 7中进行了一项实验。我使用以下代码创建了我的字体:

UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:@"Helvetica Neue" size:16.0];
UIFontDescriptor *symbolicFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic];

UIFont *fontWithDescriptor = [UIFont fontWithDescriptor:symbolicFontDescriptor size:16.0];

使用fontWithDescriptor获得了有效的UIFont,然后我使用以下代码查询字体的fontName:

[fontWithDescriptor fontName]

我回到了家中,打开了我的电脑。

HelveticaNeue-Italic

究竟怎么回事呢???

所以,一个可能的答案是上面的代码,回答了7.0.3的问题。

---- 进一步改进 ----

虽然上面的解决方案有效,但我认为它并不正式正确。我已经转而使用以下解决方案。

    UIFontDescriptor *fontDescriptor = [[UIFontDescriptor alloc] init];
    
    UIFontDescriptor *fontDescriptorForHelveticaNeue = [fontDescriptor fontDescriptorWithFamily:@"Helvetica Neue"];
    UIFontDescriptor *symbolicFontDescriptor = [fontDescriptorForHelveticaNeue fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic];
    
    textFont = [UIFont fontWithDescriptor:symbolicFontDescriptor size:textFontPointSize];

看起来这个做了所有正确的事情。我之前尝试了另一个字体系列的方法,似乎在fontName和fontFamily上混淆了。


我也看到了这个问题。不知道发生了什么,但这是相当严重的倒退。 - ipodishima
有趣的是,iOS 7.0.3上的Pages显示的是Helvetica Neue Italic字体:http://i.stack.imgur.com/xpJKl.png - Léo Natan
所以看起来你用字体描述符确实在我的7.0.3 iPhone上显示了斜体字,但是你似乎用你自己的问题和研究来回答我的问题。 - Rick van der Linde
这在iOS 7.0.4中也是一个问题。 - s.ka
10个回答

31

这是一个Apple的bug。它在iOS 7.0.3中引入,到iOS 7.0.4为止还没有被修复。在iOS 7.1的开发者预览版中似乎已经修复了。以下是解决该问题的代码(由Apple在dev论坛中提供):

#import <CoreText/CoreText.h>

CGFloat size = 14;
UIFont *font = [UIFont fontWithName:@"HelveticaNeue-Italic" size:size];
if (font == nil && ([UIFontDescriptor class] != nil)) {
    font = (__bridge_transfer UIFont*)CTFontCreateWithName(CFSTR("HelveticaNeue-Italic"), size, NULL);
}
值得注意的是,在当前版本的Xcode(5.0.1(5A2053))中,此字体未列为Interface Builder中字体下拉列表中的选项。因此,如果您以前使用此字体配置了标签,则会注意到UI混乱,并且标签最终被分配为运行时的其他字体和大小(请参见下面的UI屏幕截图)。对于在storyboards/xibs中配置的标签,您需要在代码中重置字体。

有关问题的讨论,请参考开发人员论坛中的讨论。

enter image description here


你说你已经用其他东西替换了所有的使用。你用什么替换它了?我们注意到,如果你在XIB文件中用HelveticaNeue-MediumItalic替换它,在iOS 6及更早版本上会得到不正确的结果,因为这种字体似乎是在iOS 7中引入的。 - GBegen
我将它替换为HelveticaNeue-LightItalic。不确定它是何时引入的。我的应用程序是iOS7+。 - Mike Vosseller

7

这是iOS 7.0.3中的一个错误。

如果您明确使用HelveticaNeue-Italic字体,则可以使用以下解决方法创建它:

UIFont* font = (__bridge_transfer UIFont*)CTFontCreateWithName(CFSTR("HelveticaNeue-Italic"), fontSize, NULL);

请注意,这个解决方法仅适用于iOS 7,在iOS 6上无法使用(因为 CTFontRef UIFont 在iOS 6上不是toll-free桥接)。 但是,在iOS 6上,您可以使用普通的字体查找代码。

4

我认为这是一个bug。我已经向苹果报告了这个问题。对我来说很遗憾,我的应用现在崩溃了。这种字体是我使用的第三方库中的。许多Twitter上的人都报告了问题。


1
FYI:我刚刚测试了一下,在iOS 7.0.4中仍存在这个bug。 - David Lari

3

如果您需要动态访问斜体字体,则不要通过名称访问字体,而应该使用 [UIFont italicSystemFontOfSize:15.0f]。这对我来说很有效。


这可能是解决此问题最干净的方法。如果需要支持iOS 6,则可以尝试首先运行fontWithName:size:,如果结果为nil,则运行italicSystemFontOfSize:,它应该始终返回一些内容,并且至少避免崩溃。 - SaltyNuts

2

我目前找不到会话,但他们说在iOS7上不能再依赖可用字体。它们甚至可以在应用程序生命周期内更改。这基本上意味着:当您在应用程序中指定字体时,您会遇到问题,而应使用字体描述符或首选字体!


2
我能找到的最接近的匹配是http://asciiwwdc.com/2013/sessions/223,但看起来他们指的是可下载字体,而不是系统提供的字体。 - Hilton Campbell
请参考上面的新信息。我认为演讲者的意思是,您不能指望“MetaFonts”在不同版本或使用情况下映射到相同的基础字体。我不认为他是在说像“HelveticaNeue-Italic”这样的东西会消失。 - Scott Sarnikowski

1

我曾经遇到一个问题,在iOS 7.0.3和7.0.4版本中会崩溃,但在其他所有版本中都可以正常运行。经过多次调查,我发现@"HelveticaNeue-Italic"在iOS 7.0.3和7.0.4版本中不可用,因此我会在这些版本中崩溃。

我通过以下代码解决了这个问题,这对有需要的人可能有所帮助。

self.headerFont = [UIFont fontWithName:@"HelveticaNeue-Italic" size:16.0f];
if (self.headerFont == nil) {
    self.headerFont = [UIFont fontWithName:@"HelveticaNeue" size:16.0f];
}

崩溃日志为:

[__NSCFConstantString pointSize]: unrecognized selector sent to instance 

1
这个漏洞似乎已经在iOS 7.1 beta 1中被修复。 [UIFont fontWithName:@"HelveticaNeue-Italic" size:size]; 返回一个字体。

好消息,但这仍然受NDA的限制。 - Vincent Tourraine
9
我会承担那个风险。 - Léo Natan

1
我向苹果提交的错误报告被标记为“重复关闭”。我希望这意味着他们认为这是一个错误。然而,iOS 7.0.4并没有修复这个错误。

1
我收到了同样的反馈,希望他们能够修复它。 - Scott Sarnikowski

1
我发现了另一个似乎有效的解决方案。 我记录了一个调用

[[UIFont italicSystemFontOfSize:12.0] fontName]

以查看实际使用的系统斜体字体是什么,它返回“.HelveticaNeueInterface-ItalicM3”。简单的测试表明,使用

[UIFont fontWithName:@".HelveticaNeueInterface-ItalicM3" size:12.0]

有效!在视觉上进行比较,上述调用返回的字体与原始的“HelveticaNeue-Italic”字体完全相同。

这个问题几乎肯定是一个错误... Helvetica Neue是iOS 7中的默认字体,因此该系列中的字体不应该丢失。 在Xcode v.5.0中一切正常,但在升级到5.0.1后立即出现了这个问题。 我已向Apple提交了一个错误报告。在那之前,这个解决方案似乎有效...


-1

由于没有人提到 UIWebView 中 HelveticaNeue 斜体的支持情况,我想分享一下我的发现。

截至 7.0.6 版本,UIWebView 仍然缺少常规斜体字体,并且似乎会回退到同一字体系列中的 UltraLightItalic。当它与常规权重非斜体 HelveticaNeue 文本并排时,这看起来有点奇怪,因为它要轻得多。

我的解决方法是只在斜体部分使用普通的 Helvetica,而不是 HelveticaNeue。所以,如果你有像这样的 CSS:

.myCssClass {
    font-family:HelveticaNeue;
    /* etc, etc */
}

...你需要添加另外两个类来覆盖<i><em>

.myCssClass i  { font-family:Helvetica; }
.myCssClass em { font-family:Helvetica; }

普通的Helvetica斜体字看起来很好,我认为没有人会注意到它不是HelveticaNeue。


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