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

时间:2017-04-13 18:30:14

标签: swift range nsattributedstring

我的一个控制器有一个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

我正在为控制器编写单元测试,我想验证是否在&#34;这里&#34;文本。 (链接实际上是动态生成的,这就是我想测试它的原因。)

无论如何,我显然可以得到这样的未分配文本:

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

我也可以从&#34; here&#34;获取链接属性。做这样的事情:

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

问题是我必须硬编码&#34; 6&#34;对于at参数。 linkStr的价值可能在未来发生变化,我不想每次都更新我的测试。对于这种情况,我们可以假设它总是会出现&#34; here&#34;附上该词的链接。

所以我想要做的就是找到这个词的位置&#34; here&#34;在linkStr中,并将该值传递到at参数,以便提取NSLink属性并验证它是否指向正确的网址。但是我无法在Swift中使用字符串范围和索引来解决这个问题。

有什么建议吗?

1 个答案:

答案 0 :(得分:7)

这里有没有硬编码的方法。这是基于您的样本的Swift 3游乐场代码:

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(NSLinkAttributeName , 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