Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can selection be disabled in PDFView?

Displaying a PDFDocument in a PDFView allows the user to select parts of the document and perform actions e.g. "copy" with the selection. How can selection be disabled in a PDFView while preserving the possibility for the user to zoom in and out and scroll in the PDF?

PDFView itself does not seem to offer such a property nor does the PDFViewDelegate.

like image 947
christopher.online Avatar asked Mar 04 '18 19:03

christopher.online


2 Answers

For iOS 13, the above solution no longer works. It looks like they've changed the internal implementation of PDFView and specifically how the gesture recognizers are set up. I think generally it's discouraged to do this kind of thing, but it can still be done without using any internal API, here's how:

1) Recursively gather all subviews of PDFView (see below for the helper function to do this)

let allSubviews = pdfView.allSubViewsOf(type: UIView.self)

2) Iterate over them and deactivate any UILongPressGestureRecognizers:

for gestureRec in allSubviews.compactMap({ $0.gestureRecognizers }).flatMap({ $0 }) {
    if gestureRec is UILongPressGestureRecognizer {
        gestureRec.isEnabled = false
    }
}

Helper func to recursively get all subviews of a given type:

func allSubViewsOf<T: UIView>(type: T.Type) -> [T] {
    var all: [T] = []
    func getSubview(view: UIView) {
        if let aView = view as? T {
            all.append(aView)
        }
        guard view.subviews.count > 0 else { return }
        view.subviews.forEach{ getSubview(view: $0) }
    }
    getSubview(view: self)
    return all
}

I'm calling the above code from the viewDidLoad method of the containing view controller.

I haven't yet found a good way to work this into a subclass of PDFView, which would be the preferred way for reusability and could just be an addition to the above NonSelectablePDFView. What I've tried so far is overriding didAddSubview and adding the above code after the call to super, but that didn't work as expected. It seems like the gesture recognizers are only being added at a later step, so figuring out when that is and if there's a way for the subclass to call some custom code after this happened would be a next step here.

like image 101
julsh Avatar answered Oct 02 '22 00:10

julsh


Just need to do is it will auto clear the selection and User will no longer long-press on PDF text.

class MyPDFView: PDFView {

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        self.currentSelection = nil
        self.clearSelection()

        return false
    }

    override func addGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer) {
        if gestureRecognizer is UILongPressGestureRecognizer {
            gestureRecognizer.isEnabled = false
        }

        super.addGestureRecognizer(gestureRecognizer)
    }

}

This below 2 lines need to add in canPerformAction()

self.currentSelection = nil
self.clearSelection()
like image 31
Darshit Mendapara Avatar answered Oct 01 '22 23:10

Darshit Mendapara