【问题标题】:How to use pencil (e.g. ink) annotation and finger touch navigation in PDFKit concurrently on iOS (Swift)?如何在iOS(Swift)上同时使用PDFKit中的铅笔(例如墨水)注释和手指触摸导航?
【发布时间】:2018-11-01 06:37:12
【问题描述】:

我在 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 ...")
        }
    }
}

【问题讨论】:

  • 你能发布你的实现吗?
  • 当然...我编辑了我的原始帖子。示例实现基于使用 xcode 9 的新 iOS->Single View App 项目。
  • 您是如何在 PDFView 中实现 InkAnnotation 的?我在执行此操作时遇到问题,您能告诉我吗?
  • stackoverflow.com/a/48432320/9703929 ...这个想法是我用于所有绘图代码的想法,包括墨水注释
  • 解决了吗???

标签: ios swift pdfkit pdfview


【解决方案1】:

您可以在 PDFView 的 UIGestureRecognizer 中实现所有绘图操作,也可以实现此方法。

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
{
    if touch.type == .stylus
    {
        return true
    }
    else
    {
        return false
    }
}

【讨论】:

  • 我将 PDFView 子类化并用你的代码片段覆盖了gestureRecognizer ...我可以用铅笔进行第一次触摸(开始)。但是对于绘图代码,我需要(1)铅笔笔划的开始,(2)移动和(3)结束点 - 我看不出用gestureRecognizer做这个。
  • 而且 PDF 在使用铅笔时移动,这是没用的 ;-) 如果我可以完全阻止 PDFView 使用铅笔,那就太容易了......我不需要滚动铅笔。
【解决方案2】:

可能已经晚了,但我刚刚发现自己处于完全相同的境地。所以,我找到了这个苹果的示例代码: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 方法中检查您的触摸来源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-28
    • 2018-04-06
    • 2018-04-18
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多