Custom images in UITextField such as Venmo app
I am wondering how Venmo puts custom emoji in its textbox.
When you copy these images and paste them elsewhere, they are displayed as ": sunset:", ": concert:" etc.
So, my guess is that the textField delegate checks any text that matches this pattern (ie ": concert:") and replaces it with a tiny image.
So, I'm wondering how you can put your own little UIImageView inside a textbox along with other text.
Edit: It could also be a UITextView now that I think about it
source to share
The text input in the screenshot is almost certainly a subclass UITextView
, and here I will present one way to achieve the desired result with this.
Here's a short demo, copying text containing a custom image from one UITextView
to the other:
We will first need a subclass NSTextAttachment
to have the textual representation of the image at hand, which we will later use when copying.
class TextAttachment: NSTextAttachment {
var representation: String?
}
Now, when we create an attached string containing an image, we will add the desired textual representation of the image to the application:
let attachment = TextAttachment()
attachment.image = UIImage(named: "1f197")
attachment.representation = ":anything-here:"
Next, we will subclass UITextView
and override the method copy(_:)
declared in UIResponderStandardEditActions
, which is implemented UITextView
.
class TextView: UITextView {
override func copy(_ sender: Any?) {
let selectedString = self.attributedText.attributedSubstring(from: self.selectedRange)
let enumeratableRange = NSRange(location: 0, length: selectedString.length)
let result = NSMutableAttributedString(attributedString: selectedString)
selectedString.enumerateAttribute(NSAttachmentAttributeName, in: enumeratableRange, options: []) { (value, range, _) in
if let attachment = value as? TextAttachment, let representation = attachment.representation {
result.replaceCharacters(in: range, with: representation)
}
}
UIPasteboard.general.string = result.string
}
}
We could also override a few other methods like cut(_:)
and paste(_:)
, but outside the scope of the question.
Finally, add some attributed text to your custom text view instance to see how it works in action:
var textView: TextView // Create an instance however.
let mutableString = NSMutableAttributedString()
mutableString.append(NSAttributedString(string: "Text with "))
mutableString.append(NSAttributedString(attachment: attachment))
mutableString.append(NSAttributedString(string: " text attachment."))
self.textView.attributedText = mutableString
Obviously it would be more intuitive to convert text / emoji / any to attachments on the fly during user input.
source to share