自定义安装的字体未在UILabel中正确显示


83

我正在尝试使用从Adobe Font Collection Pro软件包中获得的Helvetica Neue压缩字体。不幸的是,当我在中使用它时,它似乎绘制不正确UILabel

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

屏幕截图不正确的字体渲染

字体的粗体和常规版本都存在相同的问题。我能够从OSX中提取Helvetica Neue Bold的版本并将其放在设备上,并且显示正常(上图中的绿色背景)。

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


我可以以某种方式使UIFont的子类可以解决这些问题吗?
MikeQ 2011年

+1-对我来说同样的问题。我尝试使用ZFont来解决此问题,它确实有所帮助,但还远远不够。使用这些自定义字体来解释行距可能有些不对(确实不知道,但是我必须认为这可能与它有关!)。
Joe D'Andrea

嗨!您最终找到了解决方案吗?如果是,请回答您的问题。提前致谢。
即将

不幸的是,不,我没有。而且我不再可以访问导致此问题的原始字体文件。我喜欢kolyuchiy的回答。我只希望可以在我的特定情况下对其进行测试。
MikeQ

请注意,此问题已在iOS7中修复。
花花公子

Answers:


125

我在此处发布了涉及修补ttf字体文件的解决方案:

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

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

这将创建Bold.hhea.xml。使用文本编辑器将其打开,并增加ascenderattribute的值。您将不得不做一些试验,以找出最适合您的确切值。就我而言,我将其从750更改为1200。然后使用以下命令行再次运行该实用程序,以将您的更改重新合并到ttf文件中:

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

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


非常感谢您提出此工具的建议!也可以通过编辑“ -t名称”部分来重命名字体。
菲利普(Philippe)2012年

1
您也可以尝试Mensis或FontForge。这些应用程序也可以用于更改ascender属性。
kolyuchiy 2012年

1
你让我今天一整天都感觉很好。几个星期以来,我一直被这个问题困扰。我可以经常使用它!
TheBeardedCoda 2012年

1
请注意,通过增加上升键,您将增加行距–如果您的应用中包含多行文字,则可能会出现问题。
Pavel Alexeev 2013年

2
**请另请参见JOSEPH LIN的答案**您应该同时调整上升器并将linegap设置为零,以确保在iOS 6和iOS 7上都能良好对齐!
Ken M. Haggerty

64

因此,这是kolyuchiy答案的修改版本。

我使用Glyphs打开了字体,然后将其导出而不进行任何修改。神奇地,垂直对齐问题以某种方式消失了!

更好的是,新字体可以很好地与like之类的方法配合使用sizeWithFont:,因此不会出现Joshua提到的问题。

我接过一看HHEA表kolyuchiy提到的命令,并注意到字形修饰不只是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"

因此,故事的寓意-不仅要增加提升,而且还要修改其他相关的价值。

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


之后,我已经保存了TTF我使用再次使用的字形,字体的行为几乎是相同的的iOS 6和iOS 7,此前其基线将在iOS 6错位
leolobato

6
感谢您终于弄清楚了!显然,iOS 6支持lineGap属性,而iOS 7忽略它。解决的办法是使lineGap 0并相应地增大上升器。这正是字形做的,它适用于双方的iOS 6和iOS 7
phatmann

是。使用Fedora的免费“ Overpass”字体,将lineGap减小为零(0)并保持上升(在1991年)为我解决了问题。谢谢大家提供解决方案的指导。在iOS6和iOS7上均可使用。
stephenhouser 2014年

在使用Glyphs和OS X字体工具几次失败之后,我才得出与@phatmann相同的结论。事实是,最好将这种技巧与OS X字体工具一起使用,而不是简单地与Glyphs一起导出,因为Glyphs还会编辑字体的样式名称和后记名称,这会使xCode在某些情况下找不到字体。
2014年

32

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

解决的办法是使lineGap 0并相应地增大上升器。根据以上答案,一种解决方案是从字形导入和导出。但是,请注意,该应用程序的未来版本可能会修复此“错误”。

一个更可靠的解决方案是根据此文章自己编辑字体。特别,

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

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


4

我们的一种自定义字体存在相同的问题。我们还通过编辑font ascender属性来“解决”该问题。但是,我们发现这带来了其他问题和布局问题。例如,当使用我们的ascender编辑字体时,基于标签高度动态设置单元格高度会爆炸。

我们最终要做的是更改UIButton contentEdgetInsets属性。

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

不确定哪种方法更好,但是只是想分享另一种解决问题的方法。


2
同意 提升属性修复不是理想的解决方案
Max MacLeod

1
嗨,约书亚,我刚刚发布了一种方法,可以解决您提到的问题。简而言之,还需要与上升者一起修改其他一些属性。

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)

4

对于那些正在运行OS X El Capitan并使用此线程的用户,您可能已经注意到Apple字体工具套件不再兼容(至少现在是不兼容)。

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

使用FontForge打开字体,然后在顶部菜单中选择“元素”,然后转到“字体信息”>“ OS / 2”>“度量标准”。您要在此处编辑“ HHEad线间距”和“ HHead上升偏移量”值。

完成必要的编辑后,您只需在文件>生成字体中导出字体,然后选择正确的字体格式


3

由于有了这个答案,我解决了字形的问题,但有一些不同。

我使用Glyphs(也适用于Glyphs mini)打开了字体,并在此处找到了此部分(来自Glyphs mini,请按一下右上角的i按钮到达该部分):

在此处输入图片说明

只需删除所有对齐区域(或其中一些对齐区域),即可解决此问题。为我完美地工作。


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如果不对标签进行编程,也可以在情节提要中作为属性访问)。


1

您是否尝试过Core Text?我已经成功地通过Core Text渲染了自定义字体,但是我不知道它是否适合您的情况。


1
我可以确认核心文字没有这个问题。
13年


0

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


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文件夹。

-3

我在Sprite Kit游戏中使用标志性的“ FontAwesome”字体遇到了类似的问题。将SKLabelNode的SKLabelVerticalAlignmentMode属性设置为.Center可以为我工作。

myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Center

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.