2017-04-13 6 views
6

Einer meiner Controller in NSAttributedString Attribute zu Teilzeichenfolge Erste hat eine NSAttributeString die einen Link in sich hat:Swift 3:

@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 

ich einen Komponententest für den Controller zu schreiben und ich das überprüfen möchte, dass die Der richtige Link wurde auf den "hier" -Text gelegt. (Der Link wird tatsächlich dynamisch generiert, weshalb ich ihn testen möchte).

Wie auch immer, ich kann natürlich den unattributed Text wie diese:

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

Ich kann auch das Link-Attribut von "hier" erhalten, indem so etwas wie dies zu tun:

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

Das Problem ist, Ich musste diese "6" für den Parameter at fest codieren. Der Wert von linkStr könnte sich in Zukunft ändern und ich möchte meinen Test nicht jedes Mal aktualisieren müssen. Für diesen Fall können wir annehmen, dass es immer das Wort "hier" mit dem Link zu diesem Wort haben wird.

Also, was ich möchte zu tun, das Zeichen für finden, wo das Wort „hier“ ist in linkStr und diesen Wert in die at Parameter, um das NSLink Attribut zu ziehen vorbei und überprüfen sie nach rechts zeigen URL Aber ich habe Probleme damit, Kopf oder Zahl zu ziehen, wie man in Swift String-Bereiche und Indizes verwendet, um das zu erreichen.

Irgendwelche Vorschläge?

Antwort

5

Hier ist, wie Sie es ohne Hardcoding tun können. Dies ist Swift 3 Spielplatz Code auf der Grundlage Ihrer Probe:

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)") 
    } 
} 

Die print Anweisung Ausgänge:

http://google.com/ found at 6 
+1

Wow ... das nie erraten hätte. Swift ist ... manchmal interessant. Vielen Dank! – Chad