Храните текст и изображение вместе в AttributedString - PullRequest
0 голосов
/ 06 апреля 2019

У меня есть приписанная строка в Swift, которая отображает значок рядом с именем пользователя.Это прекрасно работает, моя реализация выглядит следующим образом:

attributedUsername = NSMutableAttributedString(string: "username")
let iconAttachment = NSTextAttachment()
let iconImage = UIImage(named: "userIcon")
iconAttachment.image = iconImage
iconAttachment.bounds = CGRect(x: 0, y: -3, width: 14, height: 14)
let iconString = NSAttributedString(attachment: verifiedAttachment)
attributedUsername.append(iconString)

usernameLabel.attributedText = attributedUsername

Однако иногда имя пользователя слишком велико, чтобы поместиться в одну строку, оборачивая имя пользователя во вторую строку (numberOfLines = 0).Это нормально, но если имя пользователя достаточно длинное, чтобы поместиться на экране, тогда изображение переносится на следующую строку.Мне интересно, есть ли способ сохранить значок, завернутый в конец имени пользователя.То, чего я хочу достичь, где * - это значок, это:

username *

longer username *

a very long
username *

вместо:

username *

longer username *

a very long username
*

Так что в основном я хочу, чтобы значок слипался с последней частьюимя пользователя (если возможно).Если имя пользователя не содержит пробелов и слишком длинное, то оно должно быть просто перенесено на следующую строку, потому что это будет стандартная реализация.Есть предложения?

1 Ответ

0 голосов
/ 06 апреля 2019

Ну, я не уверен, что вы можете сделать это, установив какой-либо параметр в NSAttributedString, но вы можете легко добиться этого с помощью простого алгоритма.

Сначала переместите код, который создает атрибутивную строку, в функцию, так как мы будем использовать ее для вычисления ширины. Не забудьте также установить атрибут шрифта, чтобы можно было получить правильный размер из приписанной строки:

func attributedString(for text: String) -> NSAttributedString {
    let attributedText = NSMutableAttributedString(string: text)
    let iconAttachment = NSTextAttachment()
    let iconImage = UIImage(named: "star")
    iconAttachment.image = iconImage
    iconAttachment.bounds = CGRect(x: 0, y: -3, width: 14, height: 14)
    let iconString = NSAttributedString(attachment: iconAttachment)
    attributedText.append(iconString)
    attributedText.setAttributes([.font: UIFont(name: "Avenir-Book", size: 15)!],
                                 range: NSRange((text.startIndex..<text.endIndex), in: text))
    return attributedText
}

Тогда:

let text = "some really really really really long usernameeeeeeeee"
let attributedText = attributedString(for: text)
let maxWidth = ... 

if attributedText.size().width > maxWidth { // A line break is required
    let lastWord = text.components(separatedBy: " ").last!
    let attributedLastWord = attributedString(for: lastWord)
    if attributedLastWord.size().width < maxWidth { // Forcing image to stick to last word
        var fixedText = text
        fixedText.insert("\n", at: text.index(text.endIndex, offsetBy: -lastWord.count))
        label.attributedText = attributedString(for: fixedText)
    } else {
        label.attributedText = attributedText
    }
} else {
    label.attributedText = attributedText
}

Конечно, вы захотите удалить развертывание силы и другие не очень хорошие практики. Это только для краткости, хотя. Я надеюсь, у вас есть идея.

...