以特定方式将 String 转换为 NSAttributedString

convert a String to NSAttributedString in a specific manner

所以我有一个看起来像这样的字符串:Swift , VisualBasic , Ruby

我想将此字符串转换为如下内容:

基本上我想在单个单词后面创建一个背景,是的,我可以使用 NSTokenField 库来获得这种行为,但我的文本不是由用户手动输入的,它是预先结构化的(来自数组),我不想要整个NSTokeField 的行为我只想要这样的外观和选择(通过选择我的意思是在退格键上单击一次清除一个单词,整个单词而不是一个字母)

好吧,我知道如何像这样更改文本的颜色

   func getColoredText(text: String) -> NSMutableAttributedString {
    let string:NSMutableAttributedString = NSMutableAttributedString(string: text)
    let words:[String] = text.componentsSeparatedByString(" ")
    var w = ""

    for word in words {
        if (word.hasPrefix("{|") && word.hasSuffix("|}")) {
            let range:NSRange = (string.string as NSString).rangeOfString(word)
            string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range)
            w = word.stringByReplacingOccurrencesOfString("{|", withString: "")
            w = w.stringByReplacingOccurrencesOfString("|}", withString: "")
            string.replaceCharactersInRange(range, withString: w)
        }
    }
    return string
}

但我不知道如何实现我想要的,如果有人能给我一些指导,那将对我很有帮助

P.s 如果我的问题不够清楚,请告诉我,我会添加更多细节

如果你想得到圆角,使用几个 UILabel 会容易得多。

如果可以接受,您可以先生成一个属性字符串数组,例如:

func getAttributedStrings(text: String) -> [NSAttributedString]
{
    let words:[String] = text.componentsSeparatedByString(" , ")

    let attributes = [NSForegroundColorAttributeName: UIColor.whiteColor(), NSBackgroundColorAttributeName: UIColor.blueColor()]

    let attribWords = words.map({
        return NSAttributedString(string: " \([=10=]) ", attributes: attributes)
    })
    return attribWords
}

对于每个属性字符串,我们需要创建 UILabel。为此,我们可以创建一个函数,传入一个 NSAttributedString 和 returns 一个 UILabel:

func createLabel(string:NSAttributedString) ->UILabel
{
    let label = UILabel()
    label.backgroundColor = UIColor.blueColor()
    label.attributedText = string
    label.sizeToFit()
    label.layer.masksToBounds = true
    label.layer.cornerRadius = label.frame.height * 0.5
    return label
}

现在我们将输入字符串转换为标签,方法是:

let attribWords = getAttributedStrings("Java , Swift , JavaScript , Objective-C , Ruby , Pearl , Lisp , Haskell , C++ , C")
let labels = attribWords.map { string in
        return createLabel(string)
    }

现在我们只需要在视图中显示它们:

let buffer:CGFloat = 3.0
var xOffset:CGFloat = buffer
var yOffset:CGFloat = buffer

let view = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 320.0, height: 400.0))
view.backgroundColor = UIColor.lightGrayColor()


for label in labels
{
    label.frame.origin.x = xOffset
    label.frame.origin.y = yOffset

    if label.frame.maxX > view.frame.maxX
    {
        xOffset = buffer
        yOffset += label.frame.height + buffer

        label.frame.origin.x = xOffset
        label.frame.origin.y = yOffset
    }

    view.addSubview(label)
    xOffset += label.frame.width + buffer
}

此时我们还可以将视图的大小调整为标签的高度,方法是:

if let labelHeight = labels.last?.frame.height
{
    view.frame.height = yOffset + labelHeight + buffer
}

将此代码放入 swift 游乐场会导致:

如果你不能使用标签,如果你想要一个可编辑的 UITextView,例如,我会放弃圆角,只说这样的话:

let attribWords = getAttributedStrings("Java , Swift , JavaScript , Objective-C , Ruby , Pearl , Lisp , Haskell , C++ , C")
let attribString = NSMutableAttributedString()
attribWords.forEach{
    attribString.appendAttributedString(NSAttributedString(string: "  "))
    attribString.appendAttributedString([=15=])
}
textView.attributedText = attribString