ios - 将文本和图像放在 AttributedString 中

标签 ios swift nsattributedstring nsmutablestring

我在 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
*

所以基本上我希望图标与用户名的最后部分粘在一起(如果可能的话)。如果用户名不包含空格且太长,则应将其换行到下一行,因为这将是标准实现。有什么建议吗?

最佳答案

好吧,我不确定您是否可以通过在 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
}

当然,您会希望删除强制展开和其他不太好的做法。不过,这些只是为了简洁。我希望你明白了。

关于ios - 将文本和图像放在 AttributedString 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55552520/

相关文章:

swift - 变量在其自己的初始值内使用,而变量在 init 之后的闭包内使用

ios - NSAttributedString 不显示段落缩进

iPhone:将文本分成框架的行

ios - 将 NSAttributedString 转换为 HTML 字符串

ios - .csv 文件的 NSMutableArray 的格式内容

ios - UIImage 裁剪出透明像素

objective-c - NSMutableDictionary 未获得预期输出。

swift - 无法在 Firebase 中使用 geoFire 存储 CLLocation 对象

在后台一段时间后将应用程序带到前台时 iOS 黑屏

ios - 如何从其他 View Controller 获取值(value)并进行比较..?