How can selection be disabled in PDFView?
You have to subclass PDFView, as such:
class MyPDFView: PDFView {
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
override func addGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer) {
if gestureRecognizer is UILongPressGestureRecognizer {
gestureRecognizer.isEnabled = false
}
super.addGestureRecognizer(gestureRecognizer)
}
}
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 UILongPressGestureRecognizer
s:
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.
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()