Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI Text doesn't fit full width while having multiple lines

Tags:

swiftui

there's an issue with SwiftUI's Text view while having multiple lines. So just look:

var body: some View {
    Text("Some word Some word Some word Some word")
        .frame(maxWidth: .infinity, alignment: .leading)
        .border(.red)
        .padding(16)
}

enter image description here

However adding one word changing the wrapping:

enter image description here

As result the view doesn't look as expected, for bigger fonts the difference become more visible:

enter image description here enter image description here enter image description here

Environment: iOS 15.2, Xcode 13 / Xcode 14b Preview and Simulator

Is there a reliable solution to wrap strings similarly as UILabel do without using UIViewRepresentable?

PS: already tried different combinations with .fixedSize() + .frame(idealWidth:) and no luck

like image 889
HotJard Avatar asked Mar 12 '26 02:03

HotJard


1 Answers

Apple is following typography rules. One of those rules is to avoid having a single word on the last line of a paragraph. This runt, as it is called, is believed to break a reader's focus due to all the white space. However, if the last word and any trailing punctuation is greater than 10 characters this rule does not apply.

No option exists to turn this rule off directly to my knowledge. But a workaround is to use trailing spaces at the end of the text where this could occur. Use enough trailing spaces to make the last line have greater than 10 characters.

Using your example, adding 7 trailing spaces works. "Some" plus 7 spaces being 11 characters:

Text("Some word Some word Some word Some word Some       ")

enter image description here

In this example, 8 trailing spaces works. "the" plus 8 spaces provides 11 characters so the rule does not apply and the line breaks where desired:

 Text("Some word to demonstrate the        ")

enter image description here

And with the trailing spaces, the layout should look ok with larger devices and when orientation changes occur. Fortunately the trailing spaces are truncated and will not create a new line on their own.

extension String {
    var padded: String { self + "           " }
}

Usage:

Text("Some word to demonstrate the".padded)

Side note: UILabel(versions 13.0, 16.1) also appears to use these typography rules by default. But a UILabel can turn off this typography rule with the line break strategy setting:

label.lineBreakStrategy = NSParagraphStyle.LineBreakStrategy()

Or like this:

label.lineBreakStrategy = []

But it doesn't appear to be available in SwiftUI yet.

like image 85
Marcy Avatar answered Mar 14 '26 07:03

Marcy