在 Swift 中,NSAttributedString 的字符比字符串多?

Posted

技术标签:

【中文标题】在 Swift 中,NSAttributedString 的字符比字符串多?【英文标题】:In Swift NSAttributedString has more characters than String? 【发布时间】:2016-03-28 06:22:16 【问题描述】:

我正在尝试向 Swift String 中的某些范围添加属性。 我在子字符串中找到了第一个和最后一个符号的范围,并将它们之间的文本(包括)涂成红色。

let mutableString = NSMutableAttributedString(string: text)
let str = mutableString.string
//Red symbols
var t = 0
let symbols = mutableString.string.characters.count
while t < symbols 
    if str[t] == "[" 
    let startIndex = t
    while str[t] != "]" 
        t += 1
    
    t += 1
    let endIndex = t

    mutableString.addAttribute(
        NSForegroundColorAttributeName,                    
        value: UIColor.redColor(),   
        range: NSMakeRange(startIndex, endIndex - startIndex))
    
    t += 1

但我发现 String 和 NSMutableAttributedString 中的范围不相等。 String 中的范围更短(此文本不是 Unicode 编码)。 有什么方法可以找到不在底层字符串中而是在 NSAttributedString 中的范围以正确找到它?

例子:

print(mutableString.length) //550
print(mutableString.string.characters.count) //548

为什么会有这种差异?

【问题讨论】:

"this text is not in Unicode encoding" that是什么意思? 是Windows CP1251编码 "它是 Windows CP1251 编码" 好吧,不,它不是。字符串是 Unicode。创建字符串时,您应该已从 Windows CP1251 转换。你现在拥有的可能是一团糟。 非常感谢。不同的长度是因为“\r\n”符号! 【参考方案1】:

是的,可以在NSMutableAttributedString 中找到范围。

例子:

let text = "[I love Ukraine!]"

var start = text.rangeOfString("[")
var finish = text.rangeOfString("]")

let mutableString = NSMutableAttributedString(string: text)

let startIndex = mutableString.string.rangeOfString("[")
let finishIndex = mutableString.string.rangeOfString("]")

游乐场的示例输出:

【讨论】:

【参考方案2】:

是的,我找到了。 Windows 行尾 "\r\n" 在 NSAttributedString 中是两个符号,但在 Swift String 中只有一个字符。 我使用检查我的代码:

let symbols = mutableString.string.characters.count
var extendedSymbols = 0
    while t < symbols 
        if str[t] == "\r\n"  extendedSymbols += 1 
        else if str[t] == "[" 
            let startIndex = t + extendedSymbols
            while str[t] != "]" 
                t += 1
            
            t += 1
            let endIndex = t + extendedSymbols

            mutableString.addAttribute(
                NSForegroundColorAttributeName,
                value: UIColor.redColor(), 
                range: NSMakeRange(startIndex, endIndex - startIndex))
        
        t += 1
    

谢谢大家的帮助!!!

【讨论】:

【参考方案3】:

区分 String 和 NSString,即使它们是相互桥接的。 String 是原生 Swift,您可以根据 String 字符索引定义一个范围。 NSString 是 Cocoa (Foundation),你根据 NSRange 定义一个范围。

【讨论】:

谢谢。我发现了类似的问题***.com/questions/29832930/… 看看我的在线书,在这个部分:apeth.com/swiftBook/ch03.html#SBmismatch 一本好书!谢谢你,马特! “类似问题”是一个很好的链接,它在performValidatedReplacement(in: NSMakeRange(0, currentString.length), with: newString) 上救了我,因为参数必须是(NSSting).length 而不是(String).count... @tontonCD 不错的侦探工作。是的,当您在 NSString Cocoa 世界中工作时,您需要留在其中。 Swift 将继续向您展示 NSStrings 作为 Swift Strings,因此您有时必须努力才能留在 NSString 世界中。

以上是关于在 Swift 中,NSAttributedString 的字符比字符串多?的主要内容,如果未能解决你的问题,请参考以下文章

swift 优雅地处理Swift中可本地化的字符串。注意:此代码在Swift 2中,需要在现代Swift中使用更新。

我可以在 Swift 3 项目中使用 Swift 2.3 框架吗?

在 Swift 项目中使用 Objective C 类中的 Swift 类

在 Swift 项目中使用 Objective C 类中的 Swift 类

swift 在Swift 5中播放音频

swift 在Swift中处理可变模型