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 text does not provide a lineHeight property (line spacing is a different beast). You could try to align the 'firstTextBaseLine' to get the desired behaviour. Alternatively, use a 'UILabel' (via 'UIViewRepresentable') with an attributed string (specify line height in the paragraph style).
To use a custom font, add the font file that contains your licensed font to your app, and then apply the font to a text view or set it as a default font within a container view. SwiftUI's adaptive text display scales the font automtically using Dynamic Type.
Learn how to use fonts in SwiftUI and customize Text view in SwiftUI with number of Font options such as design, size, weight, color and others. SwiftUI lets you customize Text by applying a .font () modifier. The default iOS font is called San Francisco and if you don’t explicitly change it, then all of your text will have the default iOS look.
The reason is that the SwiftUI framework has set a default value of nil for the lineLimit modifier. You can change the value of .lineLimit to nil and see the result: Normally the default line spacing is good enough for most situations. In case you want to alter the default setting, you can adjust the line spacing by using the lineSpacing modifier.
The UIFont class is a programmatic interface to access font characteristics and provide the system with glyph information of the font. In SwiftUI UIFont has been simplified to a system class called Font that makes it easier to set custom fonts to be used by the application!
This level of control lets us use the fixed size modifier as an alternative to layout priorities in SwiftUI. Let’s take a look at another example. In the example above, we have the horizontal stack that contains three text labels. The layout system can’t render all of them without truncating because labels have pretty big font sizes.
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)!)
.leading seems like a thing you need (and is typographically the correct way to talk about 'line spacing').
Use:
Font.system(size: 16, weight: .regular, design: .rounded)
.leading(.tight)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With