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.

enter image description here

Edit: It could also be a UITextView now that I think about it

+3


source to share


1 answer


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:

Demonstration.

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.

+2


source







All Articles