2017-11-06 7 views
3

PDFViewで表示されたiOS 11 PDFKitドキュメントで描画することを許可します。図面は最終的にPDFの内部に埋め込まれるべきです。iOS 11でインク注釈を実装するPDFKitドキュメント

後者は、ユーザーの図面に対応するUIBezierPathを使用して、PDF形式にPDF形式のPDF文書を追加することで解決しました。

しかし、UIBezierPathを作成するために、ユーザーがPDFViewの上に置くタッチを実際にどのように記録しますか?

touchesBeganをPDFViewとPDFPageでオーバーライドしようとしましたが、決して呼び出されません。私はUIGestureRecognizerを追加しようとしましたが、何も達成しませんでした。

私は後で、取得した座標を注釈に適したPDF座標に変換するために、convert(_ point:CGPoint、page:PDFPage)を使用する必要があると仮定しています。

答えて

1

私はのUIViewControllerとUIGestureRecognizerDelegateを拡張するPDFViewControllerクラスを作成することで問題を解決しました。私はサブビューとしてPDFViewを追加し、annotationモードを切り替える役目をするnavigationItemにUIBarButtonItemを追加しました。注釈トグルボタンがちょうど走る

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

pdfView.isUserInteractionEnabled = !pdfView.isUserInteractionEnabled 

私はUIBezierPathでタッチがsigningPathと呼ばれる記録し、次のコードを使用して型PDFAnnotationのcurrentAnnotationで現在の注釈を持っていますこれは本当にPDFのスクロールを無効にし、タッチイベントを受け取ることができるので、実際にはその鍵でした。

タッチイベントが記録されてPDFAnnotationに変換される方法は、PDFに書き込むときに注釈が表示され、最後にスクロール位置に関係なくPDFの正しい位置に記録されることを意味します。

正しいページで終わることを確認することは、ページ番号のハードコーディングされた0をpdfView.page(for:position、nearest:true)の値に同様に変更するだけです。

+0

このコードで 'UIGraphicsBeginImageContext(CGSize(width:800、height:600))'が実行されているかどうかは不明です。 –

+0

申し訳ありませんが、私はここに投稿するためのコードを準備していませんでした - 他の人が興味を持っていたので私は自分のコードを入れなければならなかったので、ここに例では必要ないコードが潜在的に含まれています私のアプリのための他の目的のために(まだ未完成です)。私が覚えている限りでは、他の人が文脈が開始されていないという警告を受けたので、コード行がそこにありました。 – jksoegaard

+0

あなたが私を誤解した場合、それは否定的なレビューではありませんでした。私はそれがなぜ必要なのか、それが何のために役立ったのか疑問に思いました。 私は自分の小さなUIGestureRecognizerをPDFView用にしましたが、それがなくても動作することを確認できます(シミュレータ上で警告が表示されませんでした。おそらく、デバイス上で、それは異なります)。 –

2

これは、ユーザーが注釈を付けるときに新しいビュークラス(たとえば、注釈ビュー)を作成し、PDFViewの先頭に置くことで行いました。

このビューでは、デフォルトのtouchesBegan/touchesMoved/touchesEndedメソッドを使用して、ジェスチャに続いてベジェパスを作成します。タッチが終了すると、私のビューはそれをpdfの注釈として保存します。

注:ユーザーがアノテーションの状態にあるかどうかを判断する方法が必要です。最後に

私のメインクラスの場合

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

私の注釈ビュー

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

申し訳ありませんが、私は既にトップビューを追加する必要のないソリューションを作成していました。 PDFが単一ページでなければならず、スクロールできないという意味でソリューションがあまり望ましくありません。そうしないと、注釈が間違った場所に表示されます。 – jksoegaard

+0

しかし、それが数ヶ月間返されていなくても、質問に答えることに感謝します。私はあなたの答えをupvoted! :-) – jksoegaard

関連する問題