Mendeteksi ketukan pada teks yang diatribusikan dengan Swift
Kadang-kadang untuk pemula agak sulit untuk mengetahui bagaimana mengatur sesuatu (itu untuk saya sih), jadi contoh ini sedikit lebih lengkap.
Tambahkan UITextView
ke proyek Anda.
Toko
Hubungkan UITextView
ke ViewController
dengan outlet bernamatextView
.
Atribut khusus
Kami akan membuat atribut khusus dengan membuat Ekstensi .
Catatan: Langkah ini secara teknis opsional, tetapi jika Anda tidak melakukannya, Anda perlu mengedit kode di bagian selanjutnya untuk menggunakan atribut standar seperti NSAttributedString.Key.foregroundColor
. Keuntungan menggunakan atribut khusus adalah Anda dapat menentukan nilai apa yang ingin Anda simpan dalam rentang teks yang diatribusikan.
Tambahkan file swift baru dengan File> New> File ...> iOS> Source> Swift File . Anda bisa menyebutnya apa yang Anda inginkan. Saya memanggil milik saya NSAttributedStringKey + CustomAttribute.swift .
Tempel kode berikut:
import Foundation
extension NSAttributedString.Key {
static let myAttributeName = NSAttributedString.Key(rawValue: "MyCustomAttribute")
}
Kode
Ganti kode di ViewController.swift dengan yang berikut ini. Perhatikan 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)")
}
}
}
}
Sekarang jika Anda mengetuk "w" dari "Swift", Anda akan mendapatkan hasil sebagai berikut:
character index: 1
character at index: w
You tapped on MyCustomAttribute and the value is: some value
Catatan
- Di sini saya menggunakan atribut khusus, tetapi bisa juga dengan mudah
NSAttributedString.Key.foregroundColor
(warna teks) yang memiliki nilai UIColor.green
.
- Sebelumnya tampilan teks tidak dapat diedit atau dipilih, tetapi dalam jawaban saya yang diperbarui untuk Swift 4.2 tampaknya berfungsi dengan baik tidak peduli apakah ini dipilih atau tidak.
Pelajaran lanjutan
Jawaban ini didasarkan pada beberapa jawaban lain atas pertanyaan ini. Selain ini, lihat juga