我想允许用户绘制在PDFView中查看的iOS 11 PDFKit文档。最终应将图形嵌入PDF内。

我通过使用与用户图形相对应的UIBezierPath向PDFPage添加类型为“墨水”的PDFAnnotation解决了后者。

但是,如何实际记录用户在PDFView上创建此类UIBezierPath的触摸?

我已经尝试覆盖PDFView和PDFPage上的touchesBegan,但是从未调用过它。我尝试添加UIGestureRecognizer,但未完成任何操作。

我假设以后需要使用PDFView实例方法convert(_ point:CGPoint,to page:PDFPage)将获得的坐标转换为适合注释的PDF坐标。

最佳答案

最后,我通过创建扩展UIViewController和UIGestureRecognizerDelegate的PDFViewController类解决了该问题。我将PDFView添加为 subview ,并将UIBarButtonItem添加到navigationItem,用于切换注释模式。

我将触摸记录在一个称为signingPath的UIBezierPath中,并使用以下代码在PDFAnnotation类型的currentAnnotation中包含当前注释:

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let position = touch.location(in: pdfView)
        signingPath = UIBezierPath()
        signingPath.move(to: pdfView.convert(position, to: pdfView.page(for: position, nearest: true)!))
        annotationAdded = false
        UIGraphicsBeginImageContext(CGSize(width: 800, height: 600))
        lastPoint = pdfView.convert(position, to: pdfView.page(for: position, nearest: true)!)
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let position = touch.location(in: pdfView)
        let convertedPoint = pdfView.convert(position, to: pdfView.page(for: position, nearest: true)!)
        let page = pdfView.page(for: position, nearest: true)!
        signingPath.addLine(to: convertedPoint)
        let rect = signingPath.bounds

        if( annotationAdded ) {
            pdfView.document?.page(at: 0)?.removeAnnotation(currentAnnotation)
            currentAnnotation = PDFAnnotation(bounds: rect, forType: .ink, withProperties: nil)

            var signingPathCentered = UIBezierPath()
            signingPathCentered.cgPath = signingPath.cgPath
            signingPathCentered.moveCenter(to: rect.center)
            currentAnnotation.add(signingPathCentered)
            pdfView.document?.page(at: 0)?.addAnnotation(currentAnnotation)

        } else {
            lastPoint = pdfView.convert(position, to: pdfView.page(for: position, nearest: true)!)
            annotationAdded = true
            currentAnnotation = PDFAnnotation(bounds: rect, forType: .ink, withProperties: nil)
            currentAnnotation.add(signingPath)
            pdfView.document?.page(at: 0)?.addAnnotation(currentAnnotation)
        }
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let position = touch.location(in: pdfView)
        signingPath.addLine(to: pdfView.convert(position, to: pdfView.page(for: position, nearest: true)!))

        pdfView.document?.page(at: 0)?.removeAnnotation(currentAnnotation)

        let rect = signingPath.bounds
        let annotation = PDFAnnotation(bounds: rect, forType: .ink, withProperties: nil)
        annotation.color = UIColor(hex: 0x284283)
        signingPath.moveCenter(to: rect.center)
        annotation.add(signingPath)
        pdfView.document?.page(at: 0)?.addAnnotation(annotation)
    }
}

注释切换按钮仅运行:
pdfView.isUserInteractionEnabled = !pdfView.isUserInteractionEnabled

这确实是关键,因为它禁用了在PDF上的滚动并使我能够接收触摸事件。

记录触摸事件并将其转换为PDFAnnotation的方式立即意味着该注释在PDF上书写时可见,并且最终将其记录到PDF中的正确位置-无论滚动位置如何。

确保将其最终显示在正确的页面上,只需将页面编号的硬编码0更改为pdfView.page(for:position,最近:true)值即可。

关于ios - 在iOS 11 PDFKit文档上实现墨水注释,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47135766/

10-12 22:25
查看更多