修复 SwiftUI 中自定义字体的行距

问题描述

我正在使用自定义字体 (Catamaran) 并且它的行与行之间似乎有很大的空间。例如我有这个代码

                Text("Example text that has big space between lines")
                    .linespacing(0)
                    .padding(.horizontal)
                    .font(Font.custom(FontNameManager.Catamaran.bold,size: 24.0))
                    .foregroundColor(.white)
                    .multilineTextAlignment(.center)

它看起来像这样:

Screenshot with text example from previous code

如您所见,行之间没有零空间,但它仍然有太多空间。我什至尝试将负数设置为 linespacing 方法,但它没有帮助。我能用这个做什么?我该如何解决?在 UIKit 中,我可能会使用属性字符串,我想我可以将 UILabel 用作 UIViewRepresentable,然后我可以在 SwiftUI iOS 14 中使用属性字符串。是否有一些更简单的解决方案可以“修复”任何用法的字体?我必须编辑原始 .ttf 文件吗?为什么这种字体的行之间有这个空格?

感谢您的帮助

解决方法

SwiftUI 可能会使用 hhea(水平标题表)的值来设置 Text 框的高度。在您的情况下,双体船的上升部为 1100,下降部为 540。框高度将计算为这两个值的总和:540 + 1100 = 1640。字体的 UPM(Units per Em)默认为 1000。这意味着在 SwiftUI 中,当设置 .font(.custom(...,size: 1000)) 时,Text() 的每一行都会有一个高度为 1640 的框架。

Text Box Height

.lineSpacing() 而言,SwiftUI 没有设置基线之间的间距值,而是设置两个框之间的间距值。如果您希望在下面的示例中两个框之间没有间距,很遗憾,不允许将 .lineSpacing() 设置为 -(1640-1000) = -640(负值不可接受)。

Set vs. Expected Line Spacing

更新:UIViewRepresentable 方法

但是,您可以改用 UILabel 来降低行高:

struct CustomText: UIViewRepresentable {
    let text: String
    let font: UIFont
    
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        
        label.font = font
        label.numberOfLines = 0
        
        let attributedString = NSMutableAttributedString(string: text)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = 0.6  // <- Reduce lineHeight with a <1 factor
        
        attributedString.addAttribute(NSAttributedString.Key.paragraphStyle,value: paragraphStyle,range: NSMakeRange(0,attributedString.length))
        
        label.attributedText = attributedString
        
        return label
    }
    
    func updateUIView(_ uiView: UILabel,context: Context) { }
}

用法:

CustomText(text: "Foggy Days\nGo Nowhere",font: UIFont(name: "Catamaran",size: 1000)!)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...