不幸的是,我找不到在 iOS 13 之前和之后都以相同方式工作的解决方案,并且这篇文章中的解决方案在激活 PDF 中的链接时会触发点击处理程序。
这是我想出的解决方案,根据 iOS 版本不同:
/// Since iOS 13, the way to add a properly functioning tap gesture recognizer on a `PDFView`
/// significantly changed. This class handles the setup depending on the current iOS version.
@available(iOS 11.0, *)
final class PDFTapGestureController: NSObject {
private let tapRecognizer: UITapGestureRecognizer
init(pdfView: PDFView, target: Any?, action: Selector?) {
assert(pdfView.superview != nil, "The PDFView must be in the view hierarchy")
tapRecognizer = UITapGestureRecognizer(target: target, action: action)
super.init()
if #available(iOS 13.0, *) {
// If we add the gesture on the superview on iOS 13, then it will be triggered when
// taping a link.
// The delegate will be used to make sure that this recognizer has a lower precedence
// over the default tap recognizer of the `PDFView`, which is used to handle links.
tapRecognizer.delegate = self
pdfView.addGestureRecognizer(tapRecognizer)
} else {
// Before iOS 13, the gesture must be on the superview to prevent conflicts.
pdfView.superview?.addGestureRecognizer(tapRecognizer)
}
}
}
@available(iOS 11.0, *)
extension PDFTapGestureController: UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
// Make sure we wait for the default PDFView's tap recognizers to fail
// before triggering our tap handler.
return (otherGestureRecognizer as? UITapGestureRecognizer)?.numberOfTouchesRequired == tapRecognizer.numberOfTouchesRequired
}
}
像这样使用它:
final class PDFViewController: UIViewController {
// Holds a reference to make sure it is not garbage-collected.
private var tapGestureController: PDFTapGestureController?
open override func viewDidLoad() {
super.viewDidLoad()
let pdfView = PDFView(frame: view.bounds)
pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(pdfView)
tapGestureController = PDFTapGestureController(pdfView: pdfView, target: self, action: #selector(didTap))
}
@objc private func didTap(_ gesture: UITapGestureRecognizer) {
// Necessary to clear the selection with our custom recognizer for iOS 13.
if pdfView.currentSelection != nil {
pdfView.clearSelection()
} else {
// Your tap handler...
}
}