使用 lineHeightMultiple 设置文本行高

2,164 阅读1分钟

在 iOS 文字编辑的场景中,我们想修改文本的行间距(line-height)可以采用设置NSParagraphStylelineSpacing属性这一方式,但这并不是真正意义上的设置文本行高。NSParagraphStyle对象为我们提供了minimumLineHeight用来限制文本的最小行高,不足的是这种方式局限性较大:

  1. 光标和行内文字无法居中对其;
  2. 最小行高为绝对值,无法自适应文字字体变化。

IMG_E82598CDD896-1.jpeg

lineHeightMultiple属性可以部分解决这一困惑,通过设置基础行高的倍数,我们可以把行高设置在任何合理的范围内且不用担心行间距和字体大小的影响。当然,我们还是需要通过重载NSLayoutManagerdrawGlyphsForGlyphRange:atPoint方法去调整文字和光标不对齐的问题。

override func drawGlyphs(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
    var origin = origin
    if let textStorage = textStorage {
        var range = glyphsToShow
        let attr = textStorage.attributes(at: glyphsToShow.location, effectiveRange: &range)
        if let font = attr[.font] as? UIFont,
           let paragraph = attr[.paragraphStyle] as? NSParagraphStyle {
            if paragraph.lineHeightMultiple > 1 {
                origin.y -= font.lineHeight * (paragraph.lineHeightMultiple - 1) * 0.5
            }
        }
    }
    
    super.drawGlyphs(forGlyphRange: glyphsToShow, at: origin)
}

IMG_3C78BAF9FA01-1.jpeg

另外,网络上还流转着一种通过设置baselineOffset的方式解决设置行高文字和光标不对齐问题的方案,这个也可以,只是涉及到多 paragraphStyle 文本的时候比较麻烦。