使用 Swift 检测属性文本的点击
有时对于初学者来说,知道如何设置东西有点困难(反正对我来说是这样),所以这个例子更完整一些。
UITextView
在您的项目中添加一个。
出口
使用名为 的插座将 连接UITextView
到。ViewController
textView
自定义属性
我们将通过制作Extension来制作自定义属性。
注意:此步骤在技术上是可选的,但如果您不这样做,则需要在下一部分中编辑代码以使用标准属性,例如NSAttributedString.Key.foregroundColor
. 使用自定义属性的优点是您可以定义要存储在属性文本范围中的值。
使用File > New > File... > iOS > Source > Swift File添加一个新的 swift 文件。你可以随心所欲地称呼它。我打电话给我的 NSAttributedStringKey+CustomAttribute.swift。
粘贴以下代码:
import Foundation
extension NSAttributedString.Key {
static let myAttributeName = NSAttributedString.Key(rawValue: "MyCustomAttribute")
}
代码
将 ViewController.swift 中的代码替换为以下内容。注意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)")
}
}
}
}
现在,如果您点击“Swift”的“w”,您应该会得到以下结果:
character index: 1
character at index: w
You tapped on MyCustomAttribute and the value is: some value
笔记
- 在这里,我使用了一个自定义属性,但它也可以很容易地成为
NSAttributedString.Key.foregroundColor
(文本颜色),其值为UIColor.green
.
- 以前文本视图无法编辑或选择,但在我对 Swift 4.2 的更新答案中,无论是否选择这些似乎都可以正常工作。
进一步研究
这个答案是基于这个问题的其他几个答案。除了这些,另见