Swift 3:获取NSAttributedString子字符串的属性

7

我的一个控制器有一个NSAttributeString,其中包含一个链接:

@IBOutlet var textView: UITextView!

// Below is extracted from viewDidLoad()
let linkStr = "Click <a href='http://google.com'>here</a> for good times."
let attributedText = try! NSAttributedString(
  data: linkStr.data(using: String.Encoding.unicode, allowLossyConversion: true)!,
  options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
  documentAttributes: nil)
textView.attributedText = attributedText

我正在为控制器编写单元测试,我希望验证“这里”文本上放置了正确的链接。(链接实际上是动态生成的,这就是我想要进行测试的原因)。

无论如何,我显然可以像这样获取未分配的文本:

let text = viewController.textView.attributedText.string
// text == "Click here for good times."

我也可以通过以下方式从“here”中获取链接属性:

let url = uviewController.textView.attributedText.attribute(
    "NSLink", at: 6, effectiveRange: nil)
// url == A URL object for http://google.com.

问题是我不得不在 at 参数中硬编码“6”。 linkStr 的值可能会在未来发生变化,我不想每次都更新我的测试。对于这种情况,我们可以假设它将始终具有附加到该单词的链接的单词“here”。
所以我的想法是找到 linkStr 中单词“here”的字符位置,并将该值传递给 at 参数,以便提取 NSLink 属性并验证它指向正确的URL。但我无法弄清楚如何在Swift中使用字符串范围和索引来完成此操作。
有什么建议吗?
1个回答

7

以下是不需要硬编码就能实现的方法。这是基于您提供的示例的Swift 3 playground代码:

import UIKit
import PlaygroundSupport

let linkStr = "Click <a href='http://google.com'>here</a> for good times."
let attributedText = try! NSAttributedString(
    data: linkStr.data(using: String.Encoding.unicode, allowLossyConversion: true)!,
    options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
    documentAttributes: nil)

attributedText.enumerateAttribute(NSAttributedString.Key.link, in: NSMakeRange(0, attributedText.length), options: [.longestEffectiveRangeNotRequired]) { value, range, isStop in
    if let value = value {
        print("\(value) found at \(range.location)")
    }
}

print语句输出:

http://google.com/ found at 6

注意:由于更名的原因,'NSAttributedString.Key.link'取代了'NSLinkAttributeName'。


2
哇...从来没有想到过。有时候,Swift是很有趣的。谢谢! - Chad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接