Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable UITextView to receive pasted images

I need to support pasting of images into a UITextView. With an image copied to the clipboard, the "Paste" option doesn't seem to pop up. It does when there's text on the clipboard.

This is how to override the paste option in a custom UITextView. But I need help on how to get the option to show up to begin with...

// This gets called when user presses menu "Paste" option
- (void)paste:(id)sender{

    UIImage *image = [UIPasteboard generalPasteboard].image;

    if (image) {
        NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
        textAttachment.image = image;
        NSAttributedString *imageString = [NSAttributedString attributedStringWithAttachment:textAttachment];
        self.attributedText = imageString;
    } else {
        // Call the normal paste action
        [super paste:sender];
    }
}

I came across a few related questions, but they weren't helpful for an inexperienced developer like myself: How to get UIMenuController work for a custom view?, How to paste image from pasteboard on UITextView?

like image 625
Matt Koala Avatar asked Dec 16 '15 05:12

Matt Koala


2 Answers

I answered my own question. All you have to do is have the UITextView say "I can receive pasted images" by overriding this UITextView method:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(paste:) && [UIPasteboard generalPasteboard].image)
        return YES;
    else
        return [super canPerformAction:action withSender:sender];
}

You're welcome.

like image 188
Matt Koala Avatar answered Nov 16 '22 12:11

Matt Koala


Thanks @Matt your answer helped me. Just extending your answer which may help some one,

Subclassing UITextview, which shows paste option on long press when you have image in pasteboard.

class MyTextView:UITextView {
    var onPasteImage:(()->Void)?
    override func awakeFromNib() {
        super.awakeFromNib()
    }
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(paste(_:)) && UIPasteboard.general.image != nil {
            return true
        }else{
            return super.canPerformAction(action, withSender: sender)
        }
    }
    
    override func paste(_ sender: Any?) {
        super.paste(sender)
        if UIPasteboard.general.image != nil {
            onPasteImage?()
        }
    }
}

And wait for onPasteImage closure to be called on tap paste in textview,

inputFieldForReply.textView.onPasteImage = { [weak self] in
    if let image = UIPasteboard.general.image {
        // Process pasted image
    }
}
like image 35
Gokul G Avatar answered Nov 16 '22 13:11

Gokul G