【问题标题】:How to convert Range<String.Index> to NSRange? [duplicate]如何将 Range<String.Index> 转换为 NSRange? [复制]
【发布时间】: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 解决方案均不适用于包含表情符号的字符串。

标签: ios swift string range


【解决方案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 扩展字素簇的数量。"
猜你喜欢
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
  • 2017-01-24
  • 2019-07-19
  • 2017-03-01
相关资源
最近更新 更多