Code for most bit :
extension NSAttributedStringKey {
static let imagePath = NSAttributedStringKey(rawValue: "imagePath")
}
when to setup the text display
let fullString = NSMutableAttributedString()
let imageAttachment = NSTextAttachment()
imageAttachment.image = image
let imageAttributedString: NSMutableAttributedString = NSAttributedString(attachment: imageAttachment).mutableCopy() as! NSMutableAttributedString
let customAttribute = [ NSAttributedStringKey.imagePath: imagePath ]
imageAttributedString.addAttributes(customAttribute, range: NSRange(location: 0, length: imageAttributedString.length))
fullString.append(imageAttributedString)
then in the function called by the tap action:
@objc func onImageTap(_ sender: UITapGestureRecognizer) {
let textView = sender.view as! UITextView
let layoutManager = textView.layoutManager
// location of tap in textView coordinates
var location = sender.location(in: textView)
location.x -= textView.textContainerInset.left;
location.y -= textView.textContainerInset.top;
// character index at tap location
let characterIndex = layoutManager.characterIndex(for: location, in: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
// if index is valid
if characterIndex < textView.textStorage.length {
// check if the tap location has the custom attribute
let attributeValue = textView.attributedText.attribute(NSAttributedStringKey.imagePath, at: characterIndex, effectiveRange: nil) as? String
if let value = attributeValue {
print("You tapped on \(NSAttributedStringKey.imagePath) and the value is: \(value)")
}
}
}
From there you know the tap was in the image and you have the coordinates inside the image frame, so you can use that combination to figure out where in the image was tapped.