86

我正在尝试使用从 Adob​​e Font Collection Pro Package 获得的Helvetica Neue Condensed字体。不幸的是,当我在UILabel.

行高似乎计算正确(我认为),但是当字体显示时,它与边界框的最顶部对齐。我打电话[myLabel sizeToFit]并只调整了宽度来生成这个屏幕截图:

错误字体渲染的屏幕截图

我对字体的粗体和常规版本都有同样的问题。我能够从 OSX 中提取一个Helvetica Neue Bold版本并将其放在我的设备上,它显示良好(上图中的绿色背景)。

字体文件或我的代码可能有什么问题会导致它以这种方式绘制?

4

13 回答 13

125

我在这里发布了一个涉及修补 ttf 字体文件的解决方案:

这是适用于我的自定义字体的解决方案,它在 UILabel、UIButton 等中存在相同的问题。事实证明,字体的问题在于它的 assender 属性与系统字体的值相比太小了。Ascender 是字体字符上方的垂直空白。要修复您的字体,您必须下载Apple Font Tool Suite命令行实用程序。然后使用您的字体并执行以下操作:

~$ ftxdumperfuser -t hhea -A d Bold.ttf

这将创建Bold.hhea.xml. 用文本编辑器打开它并增加ascender属性值。您将不得不进行一些试验以找出最适合您的确切值。在我的情况下,我将其从 750 更改为 1200。然后使用以下命令行再次运行该实用程序,将您的更改合并回 ttf 文件:

~$ ftxdumperfuser -t hhea -A f Bold.ttf

然后只需在您的应用程序中使用生成的 ttf 字体。

于 2011-11-29T16:33:59.133 回答
65

所以这是kolyuchiy答案的修改版本。

我用Glyphs打开我的字体,然后在不修改任何内容的情况下将其导出。不知何故,神奇地,垂直对齐问题消失了!

更好的是新字体可以很好地使用类似的方法sizeWithFont:,所以它没有Joshua提到的问题。

我使用 kolyuchiy 提到的命令查看了 HHEA 表,并注意到 Glyphs 不仅修改了. ascender,还修改了lineGapnumberOfHMetrics为我。

这是之前的原始数据:

versionMajor="1"
versionMinor="0"
ascender="780"
descender="-220"
lineGap="200"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="751"

之后:

versionMajor="1"
versionMinor="0"
ascender="980"
descender="-220"
lineGap="0"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="748"

所以这个故事的寓意——不仅要增加上升者,还要修改其他相关的值。

我不是排版专家,所以我无法真正解释原因和方式。如果有人能提供更好的解释,将不胜感激!:)

于 2013-05-28T17:28:39.030 回答
32

iOS 6 尊重字体的 lineGap 属性,而 iOS 7 忽略它。因此,只有行间距为 0 的自定义字体才能在两个操作系统中正常工作。

解决的办法是让lineGap为0,让上行者相应变大。根据上述答案,一种解决方案是从 Glyphs 导入和导出。但是,请注意,该应用程序的未来版本可能会修复此“错误”。

根据这篇文章,一个更强大的解决方案是自己编辑字体。具体来说,

  1. 安装 OS X 字体工具。
  2. 将字体指标转储到文件中:ftxdumperfuser -t hhea -A d YOUR_FONT.ttf
  3. 在编辑器中打开转储文件。
  4. ascender通过将属性的值添加到属性来编辑属性lineGap。例如,如果lineGap是 200,而ascender是 750,则制作ascender950。
  5. 设置lineGap为 0。
  6. 将更改合并到字体中:ftxdumperfuser -t hhea -A f YOUR_FONT.ttf

完成此操作后,您可能需要相应地调整 UI。

于 2013-10-23T22:55:49.293 回答
5

对于那些运行 OS X El Capitan 并来到这个线程的人,您可能已经注意到 Apple Font Tool Suite 不再兼容(至少目前是这样)。

但是您仍然可以使用免费的字体编辑软件FontForge执行kolyuchiyJoseph Lin描述的更改。

使用 FontForge 打开字体并在顶部菜单中选择 Element,然后转到 Font Info > OS/2 > Metrics。您想在此处编辑 HHEad Line Gap 和 HHead Ascent Offset 值。

完成必要的编辑后,您只需在 File > Generate Fonts 中导出字体并选择正确的字体格式

于 2015-11-11T15:59:28.827 回答
4

We had the same issue with one of our custom fonts. We also "fixed" the problem by editing the font ascender property. However, we found that this created other problems and layout issues. For example dynamically setting cell height based on label height would blow up when using our ascender edited font.

What we ended up doing was changing the UIButton contentEdgetInsets property.

yourButton.contentEdgeInsets = UIEdgeInsetsMake(-10, 0, 0, 0);

Not sure which method is better, but just wanted to share another way to fix the problem.

于 2013-04-22T18:07:42.230 回答
4
  1. 在此处下载并安装 Apple 的字体工具:https ://developer.apple.com/downloads/index.action?q=font (下载链接在底部)
  2. 打开终端并 cd 到你的字体所在的位置
  3. 运行以下命令:ftxdumperfuser -t hhea -A d MY_FONT_NAME.ttf
  4. 现在你有了一个包含一些字体属性的 xml 文件,在你的文本编辑器中编辑它
  5. 搜索“lineGap”属性并将其值加 200
  6. 保存xml文件
  7. 运行以下命令:ftxdumperfuser -t hhea -A f MY_FONT_NAME.ttf
  8. 删除xml文件
  9. 在 iOS 6 上尝试配置的字体,看看它是否看起来更好。
  10. 如果需要,您可以返回步骤 3 并添加/减去“lineGap”属性。(我最终在我的配置中添加了 250)
于 2013-10-29T21:20:51.470 回答
3

感谢这个答案,我解决了 Glyphs 的问题,但有点不同。

我用 Glyphs 打开了我的字体(也适用于 Glyphs mini)并在那里找到了这个部分(这个来自 Glyphs mini,要到达那里,请按右上角的 i 按钮):

在此处输入图像描述

只需删除所有这些对齐区域(或其中一些),它就会解决这个问题。非常适合我。

于 2015-06-21T21:43:57.493 回答
2

从标签文本创建属性文本是我的解决方法。这是一个扩展:

extension UILabel {
    /// You can call with or without param values; without will use default 2.0
    func setLineSpacing(lineSpacing: CGFloat = 2.0, lineHeightMultiple: CGFloat = 2.0) {
        guard let labelText = self.text else { return }
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }
        // (Swift 4.2 and above) Line spacing attribute
        attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        self.attributedText = attributedString
    }
}

对于我的自定义字体,我得到了我需要的结果:

self.myLabel.setLineSpacing(lineSpacing: 1.2, lineHeightMultiple: 1.2)

这通过使用NSMutableParagraphStyle()包含行高和间距属性的本机提供(@IBOutlet如果您不编写标签,也可以作为情节提要中的属性访问)。

于 2018-11-19T08:18:24.570 回答
1

你试过核心文本吗?我通过 Core Text 渲染自定义字体取得了一些成功,但我不知道它是否适合您的情况。

于 2011-06-26T03:29:51.470 回答
1

我使用了https://github.com/fonttools/fonttools - 非常易于使用且免费。就我而言,'hhea' 表中 'ascender'=1000 和 'lineGap'=0 的变化起到了作用。

基于 Trevor Harmon 的文章https://medium.com/@thetrevorharmon/how-to-use-apples-font-tools-to-tweak-a-font-a386600255ae

于 2020-01-05T09:56:35.933 回答
0

如果您在使用这些命令行实用程序时遇到问题,请尝试在窗口中使用 fontcreator。并从其设置菜单中更改字体分配器。

于 2012-07-27T06:15:16.433 回答
0

对于因找不到命令错误而在 Mac OS Mojave 上努力使用ftxdumperfuserkolyuchiy答案)的任何人:

  • 从 Apple 下载字体工具包。在https://developer.apple.com/download/more/?q=font找到它们, 为 XCode 11 选择了一个。
  • 挂载 dmg 文件
  • 进入磁盘镜像 cd /Volumes/macOS\Font\Tools
  • 将包解压缩到您选择的文件夹: pkgutil --expand-full macOS\ Font\ Tools.pkg ~/font-tools
  • CLI 工具现在在 ~/font-tools/FontCommandLineTools.pkg/Payload 中可用,您可以将文件夹添加到您的路径 ( export PATH="$PATH:$HOME/font-tools/FontCommandLineTools.pkg/Payload"),或将 utils 复制到您的 bin 文件夹。
于 2020-02-27T13:42:59.367 回答
-3

我的 Sprite Kit 游戏中的标志性“FontAwesome”字体也有类似的问题。将 SKLabelNode 的 SKLabelVerticalAlignmentMode 属性设置为 .Center 对我有用。

myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Center

只是想分享一下,以防有人遇到同样的问题。

于 2015-07-20T05:40:22.097 回答