代码之家  ›  专栏  ›  技术社区  ›  christopher.online

如何在PDFView中禁用选择?

  •  9
  • christopher.online  · 技术社区  · 6 年前

    显示 PDFDocument 在a中 PDFView 允许用户选择文档的各个部分并执行操作,例如使用所选内容进行“复制”。 如何在PDFView中禁用选择,同时保留用户在PDF中放大、缩小和滚动的可能性?

    PDF视图 其本身似乎没有提供这样的财产 PDFViewDelegate

    5 回复  |  直到 6 年前
        1
  •  7
  •   AamirR    6 年前

    您必须将PDFView子类化,如下所示:

    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)
        }
    
    }
    
        2
  •  4
  •   julsh    5 年前

    对于iOS 13,上述解决方案不再有效。看起来他们改变了 PDFView 以及手势识别器的具体设置。我认为通常不鼓励这样做,但它仍然可以在不使用任何内部API的情况下完成,方法如下:

    1) 递归收集的所有子视图 PDF视图 (请参见下面的帮助器函数以执行此操作)

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

    2) 迭代并停用任何 UILongPressGestureRecognizer s:

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

    Helper func递归获取给定类型的所有子视图:

    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
    }
    

    我正在从 viewDidLoad 包含视图控制器的方法。

    我还没有找到一个很好的方法将其转换为 PDF视图 ,这将是可重用性的首选方式,并且可能只是上述内容的补充 NonSelectablePDFView 。到目前为止,我所尝试的是 didAddSubview 并在调用后添加上述代码 super ,但这并没有像预期的那样起作用。似乎手势识别器只是在稍后的步骤中添加的,因此确定何时添加以及是否有方法让子类在发生这种情况后调用一些自定义代码将是下一步。

        3
  •  4
  •   Darshit Mendapara    4 年前

    只需要做的是,它将自动清除选择,用户将不再长按PDF文本。

    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)
        }
    
    }
    

    以下2行需要在canPerformAction()中添加

    self.currentSelection = nil
    self.clearSelection()
    
        4
  •  2
  •   Imanou Petit    5 年前

    使用Swift 5和iOS 12.3,您可以通过覆盖 addGestureRecognizer(_:) 方法和 canPerformAction(_:withSender:) a中的方法 PDFView 子类。

    import UIKit
    import PDFKit
    
    class NonSelectablePDFView: PDFView {
    
        override func addGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer) {
            (gestureRecognizer as? UILongPressGestureRecognizer)?.isEnabled = false
            super.addGestureRecognizer(gestureRecognizer)
        }
    
        override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
            return false
        }
    
    }
    

    作为之前实现的替代方案,您可以简单地切换 UILongPressGestureRecognizer isEnabled 属性到 false 在初始值设定项中。

    import UIKit
    import PDFKit
    
    class NonSelectablePDFView: PDFView {
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            if let gestureRecognizers = gestureRecognizers {
                for gestureRecognizer in gestureRecognizers where gestureRecognizer is UILongPressGestureRecognizer {
                    gestureRecognizer.isEnabled = false
                }
            }
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
            return false
        }
    
    }
    
        5
  •  0
  •   Klaus Busse    5 年前

    您应该注意,这还不足以禁用文本选择,因为还有一个UITapAndHalfRecognizer(显然是一个私有的Apple类)也可以创建选择。

    它附加到PDFDocumentView,这是PDFView的另一个私有实现细节,您不能用自己的类实现替换它。