2017-11-06 3 views
3

Ich möchte dem Benutzer erlauben, auf einem iOS 11 PDFKit-Dokument in einem PDFView angezeigt zu zeichnen. Die Zeichnung sollte letztendlich in das PDF eingebettet werden.Implementieren Sie Ink-Anmerkungen auf iOS 11 PDFKit-Dokument

Letztere habe ich gelöst, indem ich eine PDFAnnotation vom Typ "ink" zur PDFPage mit einem UIBezierPath hinzugefügt habe, der der Zeichnung des Benutzers entspricht.

Wie jedoch zeichne ich tatsächlich die Berührungen auf, die der Benutzer auf dem PDFView macht, um einen solchen UIBezierPath zu erstellen?

Ich habe versucht, berührt Berührungen auf dem PDFView und auf der PDF-Seite, aber es wird nie aufgerufen. Ich habe versucht, einen UIGestureRecognizer hinzuzufügen, aber nichts erreicht.

Ich gehe davon aus, dass ich anschließend die PDFView-Instanzmethode convert (_point: CGPoint, auf page: PDFPage) verwenden muss, um die erhaltenen Koordinaten in für die Annotation geeignete PDF-Koordinaten zu konvertieren.

Antwort

1

Am Ende löste ich das Problem durch eine PDFViewController Klasse erstellen UIViewController und UIGestureRecognizerDelegate erstreckt. Ich habe ein PDFView als Unteransicht und ein UIBarButtonItem für das navigationItem hinzugefügt, das dazu dient, den Anmerkungsmodus umzuschalten.

ich die Noten in einem UIBezierPath aufnehmen signingPath genannt und habe die aktuelle Anmerkung in currentAnnotation vom Typ PDFAnnotation mit dem folgenden 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) 
    } 
} 

Die Anmerkung Umschaltknopf gerade läuft:

pdfView.isUserInteractionEnabled = !pdfView.isUserInteractionEnabled 

Dies war wirklich der Schlüssel dazu, da dies das Scrollen auf der PDF-Datei deaktiviert und es mir ermöglicht, die Berührungsereignisse zu empfangen. Die Art und Weise, wie die Berührungsereignisse aufgezeichnet und in PDF konvertiert werden, bedeutet, dass die Anmerkung während des Schreibens auf der PDF-Datei sichtbar ist und dass sie schließlich an der richtigen Position im PDF-Dokument aufgezeichnet wird - unabhängig von der Bildlaufposition.

Sicherstellen, dass es auf der rechten Seite landet, ist nur eine Frage der ähnlichen Änderung der hartcodierten 0 für die Seitenzahl auf den Wert pdfView.page (für: Position, am nächsten: wahr).

+0

Nicht sicher, dass der 'UIGraphicsBeginImageContext (CGSize (width: 800, height: 600))' in diesem Code tut. –

+0

Entschuldigung, ich habe den Code zum Posten hier nicht vorbereitet - ich hatte das Gefühl, dass ich meinen Code jetzt aufsetzen musste, da andere Leute Interesse hatten, also enthält das Beispiel möglicherweise Code, der für das Beispiel hier nicht benötigt wird, aber da drin war für andere Zwecke für meine App (die noch nicht abgeschlossen ist). Soweit ich mich erinnere, war diese Codezeile da, weil andere Warnungen erhalten haben, dass kein Kontext gestartet wurde. – jksoegaard

+0

Entschuldigung, wenn Sie mich missverstanden haben, war es keine negative Rezension, es war als eine Frage gedacht. Ich fragte mich, warum es erforderlich war, welchem ​​Zweck es diente. Ich habe meine eigene kleine UIGestureRecognizer für eine PDFView, und ich kann bestätigen, dass es ohne es funktioniert (habe keine Warnung auf dem Simulator gesehen. Vielleicht auf einem Gerät, ist es anders) –

2

Ich habe dies getan, indem ich eine neue Ansichtsklasse erstellt habe (zB Annotate View) und oben auf die PDFView setze, wenn der Benutzer Anmerkungen hinzufügt.

Diese Ansicht verwendet die Standardmethoden touchesBegan/touchesMoved/touchesEnded, um nach der Geste einen Bezier-Pfad zu erstellen. Sobald die Berührung beendet ist, speichert meine Ansicht sie als Anmerkung auf der PDF-Datei.

Hinweis: Sie benötigen eine Möglichkeit für den Benutzer zu entscheiden, ob sie sich in einem beschriftenden Zustand befinden.

Für meine Hauptklasse

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

Meine Anmerkungsansicht

class AnnotateView: UIView { 
var path: UIBezierPath? 
var delegate: VCDelegate? 

override func touchesBegan(_ touches: Set<UITouch>, 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<UITouch>, 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<UITouch>, 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<UITouch>, 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 
} 
} 
+0

Entschuldigung - Ich hatte bereits eine Lösung erstellt, die keine Ansicht hinzufügen musste. Ihre Lösung ist weniger wünschenswert, da es bedeutet, dass die PDF-Datei eine einzelne Seite sein muss und nicht gescrollt werden kann. Andernfalls wird die Anmerkung an der falschen Stelle angezeigt. – jksoegaard

+0

Vielen Dank für die Beantwortung der Frage, auch nachdem sie einige Monate unbeantwortet geblieben war. Ich habe deine Antwort aufgefrischt! :-) – jksoegaard