Fix line spacing in custom font in SwiftUI

Lib*_*tal 6 fonts text ios line-spacing swiftui

I am using custom font (Catamaran) and it seems like it has big space between lines in it. For example I have this code:

                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)
Run Code Online (Sandbox Code Playgroud)

and it looks like this:

包含先前代码中的文本示例的屏幕截图

As you can see it doesn't have zero space between lines but it still gets too much space. I even tried to set negative numbers to lineSpacing method but it doesn't help. What can I do with this? How I can fix it? In UIKit I would probably use attributed string and I think I can use UILabel as UIViewRepresentable and then I can use attributed string in SwiftUI iOS 14. Is there some easier solution which can "fix" font for any usage? Do I have to edit original .ttf file? Why there is this space between lines in this font?

Thanks for any help

Tot*_*nai 18

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

文本框高度

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

设置行距与预期行距

更新:一种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) { }
}
Run Code Online (Sandbox Code Playgroud)

用法:

CustomText(text: "Foggy Days\nGo Nowhere",
           font: UIFont(name: "Catamaran", size: 1000)!)
Run Code Online (Sandbox Code Playgroud)