如何在iOS(Swift)上同时使用PDFKit中的铅笔(例如墨水)注释和手指触摸导航?

时间:2018-05-22 13:10:40

标签: ios swift pdfkit pdfview

我在Swift中用PDFKit编写了一个PDF注释应用程序,它使用touchesBegan / Moved / Ended在PDF上进行注释。适用于绘制注释。

为了获得铅笔触摸事件,我需要在PDFView上设置切换按钮以设置“isUserInteractionEnabled = false”,如果我进行注释并设置“isUserInteractionEnabled = true”以导航(平移/缩放)PDF文档。 使用“isUserInteraction = true”,所有触摸事件都被PDFView“吃掉”(我认为它是documentView Scrollview),并且永远不会在ViewController上调用。

pepetual切换对用户来说真的很烦人,而且无法使用。

那么我如何在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 ...")
        }
    }
}

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

可能已经晚了,但我发现自己处于完全相同的情况。因此,我找到了这个苹果的示例代码: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方法检查触摸原点。