UILabel wrong word wrap in iOS 11
Solution 1:
This is a change by Apple to prevent widowed lines. From a design perspective, it is preferred to avoid having a single word on a line of text. UILabel now breaks the line in a way that the second line of text always has at least 2 words on it.
See the answer below for an option to disable it.
Also here's a good article about "widowed" and "orphaned" text.
Solution 2:
Launching the app with the arguments -NSAllowsDefaultLineBreakStrategy NO
(an undocumented defaults setting) seems to force back to the old behavior. Alternatively, you can set NSAllowsDefaultLineBreakStrategy
to NO
in NSUserDefaults
at startup (Apple registers a default of YES
for that value when UILabel
or the string drawing code is initialized, it appears, so you would need to register an overriding value after that, or insert it into the NSArgumentDomain
, or just set the default persistently).
Apple may consider that private API and reject apps that use it; I'm not sure. I have not tried this in a shipping app. However, it does work in quick testing -- saw the setting in NSUserDefaults
and found changing it altered the behavior.
Solution 3:
Since iOS 14 you can use lineBreakStrategy
property of UILabel
instance to control this behavior.
Available values are:
NSParagraphStyle.LineBreakStrategy() // none
NSParagraphStyle.LineBreakStrategy.pushOut
NSParagraphStyle.LineBreakStrategy.hangulWordPriority
NSParagraphStyle.LineBreakStrategy.standard
To disable this behavior using Swift:
if #available(iOS 14.0, *) {
label.lineBreakStrategy = []
}
// Alternatives
// label.lineBreakStrategy = NSParagraphStyle.LineBreakStrategy()
// label.lineBreakStrategy = .init(rawValue: 0)
// label.lineBreakStrategy = .init()
To make it work on lower iOS versions, you can use NSAttributedString
:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakStrategy = []
let attributedString = NSAttributedString(string: "Your text here", attributes: [
.paragraphStyle: paragraphStyle
])
let label = UILabel()
label.attributedText = attributedString
Objective-C:
if (@available(iOS 14.0, *)) {
label.lineBreakStrategy = NSLineBreakStrategyNone;
}