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

Cha*_*had 6 range nsattributedstring swift

我的一个控制器有一个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
Run Code Online (Sandbox Code Playgroud)

我正在为控制器编写单元测试,我想验证是否在"here"文本上放置了正确的链接.(链接实际上是动态生成的,这就是我想测试它的原因).

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

let text = viewController.textView.attributedText.string
// text == "Click here for good times."
Run Code Online (Sandbox Code Playgroud)

我也可以通过这样的方式从"here"获取link属性:

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

问题是我不得不为at参数硬编码"6" .价值linkStr可能在未来发生变化,我不想每次都更新我的测试.对于这种情况,我们可以假设它将始终具有单词"here",并且链接附加到该单词.

所以我想要做的是找到"here"这个词所在的字符linkStr,并将该值传递给at参数,以便拉出NSLink属性并验证它是否指向正确的URL.但是我无法解决如何在Swift中使用字符串范围和索引来解决这个问题.

有什么建议?

Dav*_* S. 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)")
    }
}
Run Code Online (Sandbox Code Playgroud)

print语句的输出:

http://google.com/ found at 6
Run Code Online (Sandbox Code Playgroud)

  • 哇...永远不会猜到。斯威夫特……有时很有趣。谢谢! (2认同)