Предотвращение разрывов строк в части NSAttributedString

Я работаю над UILabel, который содержит большой основной текст, за которым следует меньший текст, который сообщает вам, кто это сказал:

Screenshot showing problem

В настоящее время это в основном NSAttributedString с атрибутом шрифта на маленьком тексте.

Я хотел бы настроить вещи так, чтобы большие текстовые обертывания, но небольшой текст этого не делает. Т.е., если текст будет соответствовать той же строке, что и в правильном элементе, он должен выглядеть как есть, но он будет обертываться как в левом элементе, весь текст должен появиться на следующей строке:

Screenshot showing correct behavior

HTML-эквивалент того, что я пытаюсь достичь:

Title <nobr>Subtitle</nobr>
- or -
Title <span style="white-space:nowrap">Subtitle</span>

Я пробовал преобразовать оба из них в NSAttributedStrings с помощью NSHTMLTextDocumentType и, похоже, не выполняет прямой перевод.

Ответ 1

Следуя предложению rmaddy, я смог получить эффект, который я хотел, заменив пробелы и тире своими нерегулярными альтернативами:

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 (обратите внимание на немного другой формат escape-кода):

func nobr(_ string:String) -> String {
    return string
        .stringByReplacingOccurrencesOfString(" ", withString: "\u{a0}")
        .stringByReplacingOccurrencesOfString("-", withString: "\u{2011}")
}

let username = NSAttributedString(string:nobr(hotQuestion.username, attributes:nil))

Ответ 2

В Unicode есть символ word-joiner\u2060, который предотвратит разрыв строки на своей стороне и невидим. Я использовал его для принудительного переноса слов, когда знак степени был частью слова, поэтому все слово останется в одной строке, в iOS.

Objective-C:

text = [text stringByReplacingOccurrencesOfString:@"°" withString:@"\u2060°\u2060"];