1

我在 Swift 中使用 PDFKit 编写了一个 PDF 注释应用程序,它使用 touchesBegan/Moved/Ended 在 PDF 上进行注释。非常适合绘制注释。

为了获得铅笔触摸事件,如果我进行注释并设置“isUserInteractionEnabled = true”以导航(平移/缩放)PDF文档,我需要制作一个切换按钮以在PDFView上设置“isUserInteractionEnabled = false”。使用“isUserInteraction = true”,所有触摸事件都被 PDFView“吃掉”(我认为它是 documentView Scrollview),并且永远不会在 ViewController 上调用。

永久切换对用户来说真的很烦人并且不可用。

那么如何在 ViewController 中使用 touchesBegan/Moved/Ended 覆盖,并能够通过手指触摸在 PDF 中导航(平移/缩放)而无需一直切换 isUserInteractionEnabled?

该应用程序应仅使用铅笔在 iPad 上运行。

感谢您抽出宝贵时间,拉斯

使事情更清晰的示例实现:(在 ViewController 类中:UIViewController)

override func viewDidLoad() {
    super.viewDidLoad()

    pdfView = PDFView()

    pdfView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(pdfView)

    pdfView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    pdfView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    pdfView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    pdfView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    let url = Bundle.main.url(forResource: "TestPDF", withExtension: "pdf")!
    pdfView.document = PDFDocument(url: url)

    pdfView.isUserInteractionEnabled = false //touches events are called ... annotation with pencil mode
    //pdfView.isUserInteractionEnabled = true //touches events are NEVER called ... but pan/zoom works
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("touchesBegan called!")

    if let touch = touches.first {
        if touch.type == .stylus {
            print("touchesBegan pencil annotation ...")
        }
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("touchesMoved called!")

    if let touch = touches.first {
        if touch.type == .stylus {
            print("touchesMoved pencil annotation ...")
        }
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("touchesEnded called!")

    if let touch = touches.first {
        if touch.type == .stylus {
            print("touchesEnded pencil annotation ...")
        }
    }
}
4

2 回答 2

2

You can implement all your drawing operations in PDFView's UIGestureRecognizer and implement this method also.

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
{
    if touch.type == .stylus
    {
        return true
    }
    else
    {
        return false
    }
}
于 2018-05-22T15:16:54.193 回答
0

可能为时已晚,但我刚刚发现自己处于完全相同的境地。所以,我找到了这个 Apple 的示例代码:Leveraging Touch Input for Drawing Apps!最后创建了自定义手势识别器。它仍然是非常 alpha 代码,但您会理解这个想法:

class PDFDrawingGestureRecognizer: UIGestureRecognizer {
weak var pdfView: PDFView!
private var lastPoint = CGPoint()
private var currentAnnotation : PDFAnnotation?


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first,
        let numberOfTouches = event?.allTouches?.count,
        numberOfTouches == 1 {
        state = .began

        let position = touch.location(in: pdfView)
        let convertedPoint = pdfView.convert(position, to: pdfView.currentPage!)

        lastPoint = convertedPoint
    } else {
        state = .failed
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    state = .changed

    guard let position = touches.first?.location(in: pdfView) else { return }
    let convertedPoint = pdfView.convert(position, to: pdfView.currentPage!)

    let path = UIBezierPath()
    path.move(to: lastPoint)
    path.addLine(to: convertedPoint)
    lastPoint = convertedPoint

    if currentAnnotation == nil {
        let border = PDFBorder()
        border.lineWidth = 10
        border.style = .solid

        currentAnnotation = PDFAnnotation(bounds: pdfView.bounds, forType: .ink, withProperties: [
            PDFAnnotationKey.border: border,
            PDFAnnotationKey.color: UIColor.red,
            PDFAnnotationKey.interiorColor: UIColor.red,
            ])
        let pageIndex = pdfView.document!.index(for: pdfView.currentPage!)
        pdfView.document?.page(at: pageIndex)?.addAnnotation(currentAnnotation!)
    }
    currentAnnotation!.add(path)


}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let position = touches.first?.location(in: pdfView) else {
        state = .ended
        return
    }

    let convertedPoint = pdfView.convert(position, to: pdfView.currentPage!)

    let path = UIBezierPath()
    path.move(to: lastPoint)
    path.addLine(to: convertedPoint)

    currentAnnotation?.add(path)
    currentAnnotation = nil

    state = .ended
}
}

最后,将此手势识别器添加到您的 PDFView。如果您希望手势识别器仅使用铅笔,touchesBegan请检查您的触摸来源。

于 2019-01-30T18:52:49.183 回答