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)
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
SwiftUI might use values of hhea
(Horizontal header table) to set the Text
box height. In your case, Catamaran has an ascender of 1100 and a descender of 540. The box height will be calculated as the sum of these two values: 540 + 1100 = 1640. And the UPM (Units per Em) of the font is default 1000. Which means in SwiftUI, when .font(.custom(..., size: 1000))
is set, each line of Text()
will have a frame whose height is 1640.
In terms of .lineSpacing()
, SwiftUI doesn't set the value for spacing between baselines, but spacing between two boxes instead. If you want to have no spacing between two boxes in the example below, unfortunately setting .lineSpacing()
to -(1640-1000) = -640
is not allowed (negative values not acceptable).
UPDATE: An UIViewRepresentable
Method
However, you can use UILabel
instead to reduce line height:
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) { }
}
Usage:
CustomText(text: "Foggy Days\nGo Nowhere",
font: UIFont(name: "Catamaran", size: 1000)!)