Preventing line breaks in part of an NSAttributedString
Following rmaddy's suggestion, I was able to get the effect I wanted by replacing spaces and dashes with their non-breaking alternatives:
Objective-C:
NS_INLINE NSString *NOBR(NSString *string) {
return [[string stringByReplacingOccurrencesOfString:@" " withString:@"\u00a0"]
stringByReplacingOccurrencesOfString:@"-" withString:@"\u2011"];
}
NSAttributedString *username = [[NSAttributedString alloc]
initWithString:NOBR(hotQuestion.username) attributes:nil];
...
Swift (note the slightly different escape code format):
func nobr(_ string:String) -> String {
return string
.stringByReplacingOccurrencesOfString(" ", withString: "\u{a0}")
.stringByReplacingOccurrencesOfString("-", withString: "\u{2011}")
}
let username = NSAttributedString(string:nobr(hotQuestion.username, attributes:nil))
There is also word-joiner \u2060 character in Unicode which will prevent line break on its either side and is invisible. I used it to force word wrap when degree sign was part of word, so the whole word will stay on the same line, in iOS.
Objective-C:
text = [text stringByReplacingOccurrencesOfString:@"°" withString:@"\u2060°\u2060"];
@brian-nickel great solution in Swift 5.1 and in a String extension
extension String {
var withoutLineBreak: String {
self.replacingOccurrences(of: " ", with: "\u{a0}")
.replacingOccurrences(of: "-", with: "\u{2011}")
}
}