ios - 在 iOS 11 PDFKit 文档上实现墨迹注释

标签 ios pdf touch ios11

我想让用户在 PDFView 中查看的 iOS 11 PDFKit 文档上绘图。绘图最终应嵌入到 PDF 中。

后者我通过将类型为“ink”的 PDFAnnotation 添加到 PDFPage 以及对应于用户绘图的 UIBezierPath 来解决。

但是,我如何实际记录用户在 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, nearest:true) 值的问题。

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

相关文章:

.net - ManipulationDelta - 只有平移才有值,缩放和旋转始终为 'Identity'

ios - Ionic 5 Capacitor - 如何在IOS上动态更改状态栏背景颜色

ios - 手动创建的 UIWindow 大小错误

ios - 如何在 Swift 中以编程方式创建 SplitViewController?

java - 签署 PDF 文档并以字节或流的形式获取 pdf

Lifebook P1610 Touch 上的 Linux

java - 启动画面 - 触摸即可跳过

iphone - plist 到数组 "Collection was mutated while being enumerated"异常

javascript - FPDF - 使用 PDF_JS 时在没有对话框的情况下打印

date - 如何在 Magento 中获取订单时间?