Implement ink annotations on iOS 11 PDFKit document

前端 未结 3 821
广开言路
广开言路 2021-01-31 12:47

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.

The latter I have solved by

3条回答
  •  忘了有多久
    2021-01-31 13:22

    I've done this by creating a new view class (eg Annotate View) and putting on top of the PDFView when the user is annotating.

    This view uses it's default touchesBegan/touchesMoved/touchesEnded methods to create a bezier path following the gesture. Once the touch has ended, my view then saves it as an annotation on the pdf.

    Note: you would need a way for the user to decide if they were in an annotating state.

    For my main class

    class MyViewController : UIViewController, PDFViewDelegate, VCDelegate {
    
    var pdfView: PDFView?
    var touchView: AnnotateView?
    
    override func loadView() {
       touchView = AnnotateView(frame: CGRect(x: 0, y: 0, width: 375, height: 600))
       touchView?.backgroundColor = .clear
       touchView?.delegate = self
       view.addSubview(touchView!)
    }
    
     func addAnnotation(_ annotation: PDFAnnotation) {
        print("Anotation added")
        pdfView?.document?.page(at: 0)?.addAnnotation(annotation)
    }
    }
    

    My annotation view

    class AnnotateView: UIView {
    var path: UIBezierPath?
    var delegate: VCDelegate?
    
    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        // Initialize a new path for the user gesture
        path = UIBezierPath()
        path?.lineWidth = 4.0
    
        var touch: UITouch = touches.first!
        path?.move(to: touch.location(in: self))
    }
    
    override func touchesMoved(_ touches: Set, with event: UIEvent?) {
    
        // Add new points to the path
        let touch: UITouch = touches.first! 
        path?.addLine(to: touch.location(in: self))
        self.setNeedsDisplay()
    }
    
    override func touchesEnded(_ touches: Set, with event: UIEvent?) {
    
        let touch = touches.first 
        path?.addLine(to: touch!.location(in: self))
        self.setNeedsDisplay()
        let annotation = PDFAnnotation(bounds: self.bounds, forType: .ink, withProperties: nil)
        annotation.add(self.path!)
        delegate?.addAnnotation(annotation)
    }
    
    override func touchesCancelled(_ touches: Set, with event: UIEvent?) {
        self.touchesEnded(touches, with: event)
    }
    
    override func draw(_ rect: CGRect) {
        // Draw the path
        path?.stroke()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.isMultipleTouchEnabled = false
    }
    }
    

提交回复
热议问题