美文网首页
字体与文本高度计算

字体与文本高度计算

作者: lsh_01 | 来源:发表于2019-02-22 20:01 被阅读0次

    字体

    在 iOS 9 中,新增了两个字体家族San Francisco(英文)PingFangSC(简体中文)
    其中 San Francisco 分为.SFUIText.SFUIDisplay两种字体;PingFangSC 分为PingFangSC-RegularPingFangSC-LightPingFangSC-Medium三种字体。

    在 iOS 9 之前,常用英文字体家族为Helvetica NeueHelvetica;常用简体中文字体为STHeitiSC
    其中 STHeitiSC 分为STHeitiSC-LightSTHeitiSC-Medium两种字体;STHeitiSC 字体家族在 iOS 9 中已被移除。

    这四种字体的基本属性如下:(表格中的值均为系数,乘以字号可以得到真实的值)

    属性 .SFUIText / .SFUIDisplay Helvetica Neue / Helvetica PingFangSC STHeitiSC-Light / STHeitiSC-Medium
    ascender 0.952148 0.952000 / 0.920020 1.060000 0.860000
    capheight 0.704590 0.714000 / 0.717285 0.860000 0.778000 / 0.718000
    xheight 0.526367 / 0.507812 0.517000 / 0.522949 0.600000 0.591000 / 0.531000
    base-line 0 0 0 0
    descender -0.241211 -0.213000 / -0.229980 -0.340000 -0.140000
    lineheight 1.193359 1.165000 / 1.150000 1.400000 1.000000
    leading 0 0.028000 / 0 0 1.000000(0.03)

    .SFUIText 与 .SFUIDisplay 的差异主要是字体间距的不同,Text 字体间距较大,使得在小的字体中更加易读。
    在APP里面使用了 SF 字体后,由操作系统自动选择使用 .SFUIText 还是 .SFUIDisplay。当字号小于20号时,选择 .SFUIText,否则选择 .SFUIDisplay。

    文本高度计算

    规则如下:

    1. 文本为空时,高度为字体的 lineHeight。
    2. 只有一行时,高度为字体的 lineHeight + leading。
    3. 如果 leading=0 且 lineSpacing>0,高度为 lineHeight * numOfLines + lineSpacing * (numOfLines - 1)。
    4. 如果 leading=0 且 lineSpacing<=0,高度为 lineHeight * numOfLines。
    5. 如果 leading>0 且 lineSpacing<-leading,高度为 lineHeight * numOfLines。
    6. 如果 leading>0 且 lineSpacing<0 且 lineSpacing>=-leading,高度为 lineHeight * numOfLines + (lineSpacing + leading) * (numOfLines - 1)。
    7. 如果 leading>0 且 lineSpacing>=0 且 lineSpacing<=leading,高度为 lineHeight * numOfLines + leading * (numOfLines - 1)。
    8. 如果 leading>0 且 lineSpacing>leading,高度为 lineHeight * numOfLines + lineHeight * (numOfLines - 1)。

    代码:

    func textHeight(numOfLines: Int, lineHeight: CGFloat, leading: CGFloat, lineSpacing: CGFloat) -> CGFloat {
        if numOfLines == 0 {
            return lineHeight
        }
        else if numOfLines == 1 {
            return lineHeight + leading
        }
        
        if leading == 0 {
            if linespacing > 0 {
                return lineHeight * CGFloat(numOfLines) + linespacing * CGFloat(numOfLines - 1)
            } else {
                return lineHeight * CGFloat(numOfLines)
            }
        }
        else if leading > 0 {
            if linespacing < -leading {
                return lineHeight * CGFloat(numOfLines)
            }
            else if linespacing < 0 {
                return lineHeight * CGFloat(numOfLines) + (linespacing + leading) * CGFloat(numOfLines - 1)
            }
            else if linespacing <= leading {
                return lineHeight * CGFloat(numOfLines) + leading * CGFloat(numOfLines - 1)
            }
            else {
                return lineHeight * CGFloat(numOfLines) + linespacing * CGFloat(numOfLines - 1)
            }
        }
        else {
            fatalError("leading of font < 0")
        }
    }
    

    其他需要注意的事项:

    1. 计算文本高度时,必须包含 NSStringDrawingUsesLineFragmentOrigin 参数,否则只能是单行。
    2. 计算文本高度时,如果不包含 NSStringDrawingUsesFontLeading 参数,leading 为 0;否则取字体的 leading。
    3. Heiti SC 的 leading 值为 1.00,但参与计算的值是 0.03。
    4. iOS 9 开始 Heiti SC 会被强制替换为 PingFangSC。
    5. 由于 Heiti SC 的 lineHeight=1,而 PingFangSC 的 lineHeight=1.4,iOS 9 前后的汉字行间距存在差异。
    6. iOS 9 开始默认英文字体为 SF 系列,原有的 Helvetica 系列仍然可以使用。
    7. San Francisco 系列中的 SF 用在 OS X 和 iOS 中,SF Compact 用在 Watch OS 中。

    相关文章

      网友评论

          本文标题:字体与文本高度计算

          本文链接:https://www.haomeiwen.com/subject/delyyqtx.html