在iOS 11 PDFKit文档上实现墨迹注释 [英] Implement ink annotations on iOS 11 PDFKit document

查看:1457
本文介绍了在iOS 11 PDFKit文档上实现墨迹注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to allow the user to draw on an iOS 11 PDFKit document viewed in a PDFView. The drawing should ultimately be embedded inside the PDF.

后者我通过向PDFPage添加类型为ink的PDFAnnotation解决了问题,其中UIBezierPath对应于用户的绘图。

The latter I have solved by adding a PDFAnnotation of type "ink" to the PDFPage with a UIBezierPath corresponding to the user's drawing.

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

However, how do I actually record the touches the user makes on top of the PDFView to create such an UIBezierPath?

我已尝试在PDFView和PDFPage上覆盖touchesBegan,但从未调用过。我试过添加一个UIGestureRecognizer,但没有做任何事情。

I have tried overriding touchesBegan on the PDFView and on the PDFPage, but it is never called. I have tried adding a UIGestureRecognizer, but didn't accomplish anything.

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

I'm assuming that I need to afterwards use the PDFView instance method convert(_ point: CGPoint, to page: PDFPage) to convert the coordinates obtained to PDF coordinates suitable for the annotation.

推荐答案

最后我解决了问题通过创建扩展UIViewController和UIGestureRecognizerDelegate的PDFViewController类。我添加了一个PDFView作为子视图,一个UIBarButtonItem添加到navigationItem,用于切换注释模式。

In the end I solved the problem by creating a PDFViewController class extending UIViewController and UIGestureRecognizerDelegate. I added a PDFView as a subview, and a UIBarButtonItem to the navigationItem, that serves to toggle annotation mode.

我记录了一个名为signingPath的UIBezierPath中的触摸,并拥有使用以下代码在currentAnnotation类型PDFAnnotation中的当前注释:

I record the touches in a UIBezierPath called signingPath, and have the current annotation in currentAnnotation of type PDFAnnotation using the following code:

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

注释切换按钮刚刚运行:

The annotation toggle button just runs:

pdfView.isUserInteractionEnabled = !pdfView.isUserInteractionEnabled

这真的是它的关键,因为这会禁用PDF上的滚动和使我能够接收触摸事件。

This was really the key to it, as this disables scrolling on the PDF and enables me to receive the touch events.

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

The way the touch events are recorded and converted into PDFAnnotation immediately means that the annotation is visible while writing on the PDF, and that it is finally recorded into the correct position in the PDF - no matter the scroll position.

确保它最终出现在右页只是同样改变硬编码的问题0表示页面编号为pdfView.page(for:position,nearest:true)值。

Making sure it ends up on the right page is just a matter of similarly changing the hardcoded 0 for page number to the pdfView.page(for: position, nearest:true) value.

这篇关于在iOS 11 PDFKit文档上实现墨迹注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆