Apple的PDFKit:使用Ink注释自由绘制

时间:2018-02-21 20:53:43

标签: ios annotations pdfkit

我只想使用PDFKit在PDF文件上绘图。这听起来很简单,但我遇到了很多麻烦。从文档中,墨迹注释似乎适合于此。这是我的代码:

/// Adds a new annotation
func addAnnotation(color: UIColor, point: CGPoint) {
    currentPage = pdfView.page(for: point, nearest: false)

    // Here I convert the coordinates to the document and create a new annotation
    if currentPage != nil {
        let topRight = pdfView.convert(pdfView.frame.topRightCorner, to: currentPage!)
        newAnnotation = PDFAnnotation(bounds: CGRect(origin: .zero, size: CGSize(width: topRight.x, height: topRight.y)), forType: .ink, withProperties: nil)
        newAnnotation!.color = color
        currentPage!.addAnnotation(newAnnotation!)
    }
    else {
        newAnnotation = PDFAnnotation()
    }
}

/// Adds a new path, maybe a new annotation
func addPath(color: UIColor, point: CGPoint, lineWidth: CGFloat) {

    // Create annotation
    if newAnnotation == nil {
        addAnnotation(color: color, point: point)
    }

    guard currentPage != nil else { return }

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

    // Create initial path
    let path = UIBezierPath()
    path.lineWidth = 200
    path.move(to: convertedPoint)
    path.addLine(to: convertedPoint)
    newAnnotation!.add(path)
}

/// Updates the last drawn annotation
func updatePath(point: CGPoint) {
    if let annotation = newAnnotation, let page = currentPage {
        let convertedPoint = pdfView.convert(point, to: page)
        let lastPath = annotation.paths!.last!
        lastPath.addLine(to: convertedPoint)
        annotation.remove(lastPath)
        annotation.add(lastPath)
    }
}

我的主要问题是表现。我写了所有这些代码只是为了有一个功能性的绘图程序。我在这个过程中理解的是:

  • 对注释中的路径进行分组而不是每个路径有一个注释似乎更有效。所以我添加了addAnnotation()方法,它有时会创建一个新的注释。
  • 创建注释时的'bounds'属性在性能方面起着重要作用。将此属性设置为页面的边界会使程序变得非常慢。但事实是,在用户完成绘制之前我不知道注释的界限...
  • 我有一个方法touchMoved(),我想在路径中添加一个点。起初,我只是在做:

    if let annotation = newAnnotation, let page = currentPage {
        let convertedPoint = pdfView.convert(point, to: page)
        let lastPath = annotation.paths!.last!
        lastPath.addLine(to: convertedPoint)
    }
    

但路径没有更新,所以我添加了一行:

    annotation.remove(lastPath)
    annotation.add(lastPath)

事实证明这在演出方面非常糟糕(路径有时会消失,之后会重新出现)。

我假设有更好的方法来做所有这些,但我找不到任何好的例子。如果你在PDFKit上有一个Ink注释的工作示例,那也很棒。

附带问题:在我的代码中,我将bezierPath的lineWidth设置为200.这是因为我想更改注释的lineWidth,但更改bezierPath的lineWidth似乎没有任何改变。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我的观察结果与你的相似。我发现操纵PDFAnnotation很麻烦,主要是因为一个bug(PDFAnnotation with PDFAnnotationSubtype equal to .widget is not refreshing its appearance after adding it to PDFPage)。 删除和读取它们到PDFView的伎俩是一个讨厌的解决方法。

尝试不同的方法可能会更好吗? 例如:

  1. 使用CGLayer在PDFView的顶部绘制(透明)CoreGraphics
  2. 将绘图图层转换为UIImage
  3. 将带图片的注释添加到PDFView。您可以查看Apple示例以了解如何执行此操作。 https://developer.apple.com/library/content/samplecode/PDFAnnotationEditor/Introduction/Intro.html#//apple_ref/doc/uid/DTS10004035