Swift ile atfedilen metinde dokunmaları algılama
Bazen yeni başlayanlar için bir şeyleri nasıl ayarlayacağını bilmek biraz zor (zaten benim içindi), bu yüzden bu örnek biraz daha dolgun.
UITextView
Projenize bir ekleyin .
Çıkış
Bağlayın UITextView
üzere ViewController
adında bir çıkış ile textView
.
Özel özellik
Bir Uzantı yaparak özel bir nitelik oluşturacağız .
Not: Bu adım teknik olarak isteğe bağlıdır, ancak bunu yapmazsanız, gibi standart bir öznitelik kullanmak için sonraki bölümde kodu düzenlemeniz gerekecektir NSAttributedString.Key.foregroundColor
. Özel bir öznitelik kullanmanın avantajı, ilişkilendirilmiş metin aralığında hangi değerleri depolamak istediğinizi tanımlayabilmenizdir.
Dosya> Yeni> Dosya ...> iOS> Kaynak> Swift Dosyası ile yeni bir swift dosyası ekleyin . Ona ne istersen diyebilirsin. Benim NSAttributedStringKey + CustomAttribute.swift'i arıyorum .
Aşağıdaki kodu yapıştırın:
import Foundation
extension NSAttributedString.Key {
static let myAttributeName = NSAttributedString.Key(rawValue: "MyCustomAttribute")
}
kod
ViewController.swift'teki kodu aşağıdaki ile değiştirin. Not edin 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)")
}
}
}
}
Şimdi "Swift" in "w" ye dokunursanız, aşağıdaki sonucu almalısınız:
character index: 1
character at index: w
You tapped on MyCustomAttribute and the value is: some value
notlar
- Burada özel bir öznitelik kullandım, ancak
NSAttributedString.Key.foregroundColor
bir değeri olan (metin rengi) aynı derecede kolay olabilirdi UIColor.green
.
- Eskiden metin görünümü düzenlenebilir veya seçilebilir olamazdı, ancak Swift 4.2 için güncellenmiş cevabımda, bunların seçilip seçilmediğine bakılmaksızın iyi çalışıyor gibi görünüyor.
İlerideki çalışma
Bu cevap, bu soruya verilen diğer birkaç cevaba dayanıyordu. Bunların yanında ayrıca bakınız