iosswiftiphonexcodeswiftui

How to set line height for a single line text in SwiftUI?


Currently, I have been using .lineSpacing(...), but this only works for multi-line text.

/// Sets the amount of space between lines of text in this view.
///
/// - Parameter lineSpacing: The amount of space between the bottom of one
///   line and the top of the next line.
@inlinable public func lineSpacing(_ lineSpacing: CGFloat) -> some View

What this means is that it's harder for me to translate fonts exactly from sketch/figma, and I need to play around with the padding to get it right. Here is an example that shows this:

VStack {
    // Line spacing is ignored.
    Text("Hello, World!")
        .background(Color.green)
        .lineSpacing(50)

    Spacer()

    // Line spacing is correct.
    Text("Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups.")
        .background(Color.green)
        .lineSpacing(50)
}

Solution

  • Based on the answer by Dan Hassan I made myself a ViewModifier to do this, and it looks like it works as intended

    import SwiftUI
    
    struct FontWithLineHeight: ViewModifier {
        let font: UIFont
        let lineHeight: CGFloat
    
        func body(content: Content) -> some View {
            content
                .font(Font(font))
                .lineSpacing(lineHeight - font.lineHeight)
                .padding(.vertical, (lineHeight - font.lineHeight) / 2)
        }
    }
    
    extension View {
        func fontWithLineHeight(font: UIFont, lineHeight: CGFloat) -> some View {
            ModifiedContent(content: self, modifier: FontWithLineHeight(font: font, lineHeight: lineHeight))
        }
    }