Erkennen von Abgriffen auf zugeordneten Text mit Swift
Manchmal ist es für Anfänger etwas schwierig zu wissen, wie man Dinge einrichtet (es war sowieso für mich), daher ist dieses Beispiel etwas ausführlicher.
Fügen Sie UITextView
Ihrem Projekt ein hinzu.
Auslauf
Schließen Sie das UITextView
an die ViewController
mit einem benannten Auslass textView
.
Benutzerdefiniertes Attribut
Wir werden ein benutzerdefiniertes Attribut erstellen, indem wir eine Erweiterung erstellen .
Hinweis: Dieser Schritt ist technisch optional. Wenn Sie ihn jedoch nicht ausführen, müssen Sie den Code im nächsten Teil bearbeiten, um ein Standardattribut wie zu verwenden NSAttributedString.Key.foregroundColor
. Der Vorteil der Verwendung eines benutzerdefinierten Attributs besteht darin, dass Sie definieren können, welche Werte im zugeordneten Textbereich gespeichert werden sollen.
Fügen Sie eine neue schnelle Datei mit Datei> Neu> Datei ...> iOS> Quelle> Schnelle Datei hinzu . Sie können es so nennen, wie Sie wollen. Ich rufe meinen NSAttributedStringKey + CustomAttribute.swift auf .
Fügen Sie den folgenden Code ein:
import Foundation
extension NSAttributedString.Key {
static let myAttributeName = NSAttributedString.Key(rawValue: "MyCustomAttribute")
}
Code
Ersetzen Sie den Code in ViewController.swift durch den folgenden. Beachten Sie die UIGestureRecognizerDelegate
.
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Create an attributed string
let myString = NSMutableAttributedString(string: "Swift attributed text")
// Set an attribute on part of the string
let myRange = NSRange(location: 0, length: 5) // range of "Swift"
let myCustomAttribute = [ NSAttributedString.Key.myAttributeName: "some value"]
myString.addAttributes(myCustomAttribute, range: myRange)
textView.attributedText = myString
// Add tap gesture recognizer to Text View
let tap = UITapGestureRecognizer(target: self, action: #selector(myMethodToHandleTap(_:)))
tap.delegate = self
textView.addGestureRecognizer(tap)
}
@objc func myMethodToHandleTap(_ sender: UITapGestureRecognizer) {
let myTextView = sender.view as! UITextView
let layoutManager = myTextView.layoutManager
// location of tap in myTextView coordinates and taking the inset into account
var location = sender.location(in: myTextView)
location.x -= myTextView.textContainerInset.left;
location.y -= myTextView.textContainerInset.top;
// character index at tap location
let characterIndex = layoutManager.characterIndex(for: location, in: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
// if index is valid then do something.
if characterIndex < myTextView.textStorage.length {
// print the character index
print("character index: \(characterIndex)")
// print the character at the index
let myRange = NSRange(location: characterIndex, length: 1)
let substring = (myTextView.attributedText.string as NSString).substring(with: myRange)
print("character at index: \(substring)")
// check if the tap location has a certain attribute
let attributeName = NSAttributedString.Key.myAttributeName
let attributeValue = myTextView.attributedText?.attribute(attributeName, at: characterIndex, effectiveRange: nil)
if let value = attributeValue {
print("You tapped on \(attributeName.rawValue) and the value is: \(value)")
}
}
}
}
Wenn Sie nun auf das "w" von "Swift" tippen, sollten Sie das folgende Ergebnis erhalten:
character index: 1
character at index: w
You tapped on MyCustomAttribute and the value is: some value
Anmerkungen
- Hier habe ich ein benutzerdefiniertes Attribut verwendet, aber es hätte genauso gut
NSAttributedString.Key.foregroundColor
(Textfarbe) sein können, das einen Wert von hat UIColor.green
.
- Früher konnte die Textansicht nicht bearbeitet oder ausgewählt werden, aber in meiner aktualisierten Antwort für Swift 4.2 scheint sie einwandfrei zu funktionieren, unabhängig davon, ob diese ausgewählt sind oder nicht.
Weitere Studie
Diese Antwort basierte auf mehreren anderen Antworten auf diese Frage. Daneben siehe auch