Zach Fross
Zach Fross

Reputation: 31

iOS Swift: How to access selected text in WKWebView

I would like to be able to use a menu button to copy selected text from a web page in WKWebView to the pasteboard. I would like to get the text from the pasteboard into a text view in a second view controller. How do I access and copy the selected text in the WKWebView?

Upvotes: 1

Views: 1670

Answers (1)

James
James

Reputation: 5104

Swift 4

You can access the general pasteboard with the following line:

let generalPasteboard = UIPasteboard.general

In the view controller, you can add an observer to observe when something is copied to the pasteboard.

override func viewDidLoad() {
    super.viewDidLoad()

    // https://stackoverflow.com/questions/35711080/how-can-i-edit-the-text-copied-into-uipasteboard
    NotificationCenter.default.addObserver(self, selector: #selector(pasteboardChanged(_:)), name: UIPasteboard.changedNotification, object: generalPasteboard)
}

override func viewDidDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(UIPasteboard.changedNotification)
    super.viewDidDisappear(animated)
}    

@objc
func pasteboardChanged(_ notification: Notification) {
    print("Pasteboard has been changed")
    if let data = generalPasteboard.data(forPasteboardType: kUTTypeHTML as String) {
        let dataStr = String(data: data, encoding: .ascii)!
        print("data str = \(dataStr)")
    }
}

In the above pasteboardChanged function, I get the data as HTML in order to display the copied as formatted text in a second controller in a WKWebView. You must import MobileCoreServices in order to reference the UTI kUTTypeHTML. To see other UTI's, please see the following link: Apple Developer - UTI Text Types

import MobileCoreServices

In your original question, you mentioned you want to put the copied content into a second textview. If you want to keep the formatting, you will need to get the copied data as RTFD then convert it to an attributed string. Then set the textview to display the attributed string.

let rtfdStringType = "com.apple.flat-rtfd"

// Get the last copied data in the pasteboard as RTFD
if let data = pasteboard.data(forPasteboardType: rtfdStringType) {
    do {
        print("rtfd data str = \(String(data: data, encoding: .ascii) ?? "")")
        // Convert rtfd data to attributedString
        let attStr = try NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtfd], documentAttributes: nil)

        // Insert it into textview
        print("attr str = \(attStr)")
        copiedTextView.attributedText = attStr
    }
    catch {
        print("Couldn't convert pasted rtfd")
    }
}

Because I don't know your exact project or use case so you may need to alter the code a little but I hope I provided you with pieces you need for project. Please comment if there's anything I missed.

Upvotes: 1

Related Questions