NSMutableAttributedString:如何检索某个范围内的属性

时间:2018-11-27 15:45:09

标签: swift nsattributedstring

我已经建立了一个简单的游乐场来演示在检索属性字符串的属性时遇到的问题。也许我不明白如何定义范围:也许我错过了其他东西。

我定义了一个NSMutableAttributedString,它具有两种颜色,并且将字体更改为粗体(蓝色)和斜体(红色):

var someText =  NSMutableAttributedString()

let blueAttri : [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12), NSAttributedString.Key.foregroundColor : UIColor.blue]
let redAttri : [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.italicSystemFont(ofSize: 12), NSAttributedString.Key.foregroundColor : UIColor.red]

someText = NSMutableAttributedString(string: "Some blue string here; ", attributes: blueAttri)
someText.append(NSMutableAttributedString(string: "Some red string here; ", attributes: redAttri))

此时,该字符串看起来不错,可以同时显示两种颜色的文本。

然后我定义了3个范围(尝试使用不同的方法来定义范围)。

var range1 = NSRange()
var range2 = NSRange(location: 0, length: someText.length)
var range3 = NSRange(location: 40, length: 44)

最后,我尝试检索文本的属性

// retrieve attributes
let attributes1 = someText.attributes(at: 0, effectiveRange: &range1)

// iterate each attribute
print("attributes1")
for attr in attributes1 {
    print(attr.key, attr.value)
}

let attributes2 = someText.attributes(at: 0, effectiveRange: &range2)

// iterate each attribute
print("attributes2")
for attr in attributes2 {
    print(attr.key, attr.value)
}


let attributes3 = someText.attributes(at: 0, effectiveRange: &range3)

// iterate each attribute
print("attributes3")
for attr in attributes3 {
    print(attr.key, attr.value)
}

我得到以下结果。在所有情况下,仅显示第一组属性。

attributes1
NSAttributedStringKey(_rawValue:NSColor)UIExtendedSRGBColorSpace 0 0 1 1
  NSAttributedStringKey(_rawValue:NSFont)字体家族:“ .SFUIText-Semibold”; font-weight:粗体;字体样式:正常;字体大小:12.00pt

attributes2
NSAttributedStringKey(_rawValue:NSColor)UIExtendedSRGBColorSpace 0 0 1 1 NSAttributedStringKey(_rawValue:NSFont)字体家族:“ .SFUIText-Semibold”; font-weight:粗体;字体样式:正常;字体大小:12.00pt

attributes3
NSAttributedStringKey(_rawValue:NSColor)UIExtendedSRGBColorSpace 0 0 1 1
NSAttributedStringKey(_rawValue:NSFont)字体家族:“ .SFUIText-Semibold”; font-weight:粗体;字体样式:正常;字体大小:12.00pt

我该怎么做才能获取字符串中的所有属性?

已建议我使用枚举属性。这似乎不合法。见下文: enter image description here

2 个答案:

答案 0 :(得分:1)

对于所有三个呼叫,您正在使用attributes值为at:的{​​{1}}。返回字符串中第一个字符的属性。

如果要在一个范围内使用所有属性,请使用0并传递要迭代的范围。

注意:您传递的范围必须基于字符串的UTF-16编码,而不是Swift字符串的长度。当您使用特殊字符(例如表情符号)时,这两个长度可能会不同。使用enumerateAttributes很好。

答案 1 :(得分:0)

使用enumerateAttributes,我能够使用斜体来捕获范围(仅显示一个示例)。以下是完整的代码:

//Create Empty Dictionaries for storing results
var attributedFontRanges = [String: UIFont]()
var attributedColorRanges = [String: UIColor]()

//Find all attributes in the text.
someText.enumerateAttributes(in: NSRange(location: 0, length: someText.length)) { (attributes, range, stop) in

    attributes.forEach { (key, value) in
        switch key {

        case NSAttributedString.Key.font:
            attributedFontRanges[NSStringFromRange(range)] = value as? UIFont

        case NSAttributedString.Key.foregroundColor:
            attributedColorRanges[NSStringFromRange(range)] = value as? UIColor

        default:

            assert(key == NSAttributedString.Key.paragraphStyle, "Unknown attribute found in the attributed string")
        }
}
}

//Determine key(range) of Italic font
var italicRange = attributedFontRanges.filter { $0.value.fontName == ".SFUIText-Italic" }.keys

print("italicRange: \(italicRange)")

将打印以下结果: italicRange:[“ {23,22}”]