如何将 Range<String.Index> 转换为 NSRange? [复制]

Posted

技术标签:

【中文标题】如何将 Range<String.Index> 转换为 NSRange? [复制]【英文标题】:How to convert Range<String.Index> to NSRange? [duplicate] 【发布时间】:2017-08-03 20:18:58 【问题描述】:

如何在 Swift (Range<String.Index> 转换为 NSRange 而无需先将 String 转换为 NSString

我想这样做的原因是我想使用Range&lt;String.Index&gt; 值设置UITextViewselectedText 属性。

替代解决方案:如何将UITextInput.selectedTextRange 设置为Range&lt;String.Index&gt; 值?

【问题讨论】:

欺骗? NSRange from Swift Range?。有什么理由不想桥接到 NSString?此外,该问题的答案中有一些非 NSString 解决方案。 NSString 的桥接看起来并不纯粹、直观、易于理解、自我记录、可读、简单、美观或高效。该问题的非NSString 解决方案均不适用于包含表情符号的字符串。 【参考方案1】:

对字符串的 UTF16 视图使用 String.Index 的 samePosition(in:) 方法。 NSString 使用 UTF16,因此 UTF16 索引应该与 NSString 期望的 NSRange 索引相同。

编辑:

public extension NSRange 
    private init(string: String, lowerBound: String.Index, upperBound: String.Index) 
        let utf16 = string.utf16

        let lowerBound = lowerBound.samePosition(in: utf16)
        let location = utf16.distance(from: utf16.startIndex, to: lowerBound)
        let length = utf16.distance(from: lowerBound, to: upperBound.samePosition(in: utf16))

        self.init(location: location, length: length)
    

    public init(range: Range<String.Index>, in string: String) 
        self.init(string: string, lowerBound: range.lowerBound, upperBound: range.upperBound)
    

    public init(range: ClosedRange<String.Index>, in string: String) 
        self.init(string: string, lowerBound: range.lowerBound, upperBound: range.upperBound)
    

【讨论】:

在我写答案时它没有被标记为重复。看起来重复标记在我提交之前就在里面吱吱作响。 好吧,比起其他任何人,我更喜欢你的回答。您能否提供我可以调用的方法的代码:NSRange(range, in: string) 其实我以前也有过这样的方法。当我将所有代码升级到 Swift 4 时,我删除了它,但我可能可以将它从 git 存储库中挖掘出来。不幸的是,它必须等待几天,因为我的开发机器在商店里需要太长时间才能更换膨胀的电池。还记得我们以前只能弹出旧的和新的吗?现在你似乎已经有一个星期没带笔记本电脑了。 终于找回来了。将其添加为编辑。 这似乎是一个简单而强大的解决方案。但是在测试之后,当使用转换后的 NSRange 替换子字符串时,我得到了一个不匹配的结果。在 Swift 语言指南中,有一条关于它的注释:“count 属性返回的字符数并不总是与包含相同字符的 NSString 的长度属性相同。NSString 的长度是基于关于字符串的 UTF-16 表示中 16 位代码单元的数量,而不是字符串中 Unicode 扩展字素簇的数量。"

以上是关于如何将 Range<String.Index> 转换为 NSRange? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

无法将类型“Range<String.Index>”(又名“Range<String.CharacterView.Index>”)的值转换为预期的参数类型“NSRange”(又

无法转换类型“Range<Int>?”的值到预期的参数类型'Range<String.Index>?

如何在 NSRange 中转换范围? [复制]

java.lang.IndexOutOfBoundException错误通用Mapper插件 String index out of range: 0错误

Android Studio Error:String index out of range:-1

Hibernate String index out of range 0 异常的一种情况