作者:hanhff | 来源:互联网 | 2023-01-10 08:43
我想允许用户在PDFView中查看iOS 11 PDFKit文档.图纸最终应嵌入PDF中.
后者我通过向PDFPage添加类型为"ink"的PDFAnnotation来解决,其中UIBezierPath对应于用户的绘图.
但是,如何实际记录用户在PDFView上创建的触摸以创建这样的UIBezierPath?
我已经尝试在PDFView和PDFPage上覆盖touchesBegan,但它永远不会被调用.我试过添加一个UIGestureRecognizer,但没有做任何事情.
我假设我需要事后使用PDFView实例方法convert(_ point:CGPoint,to page:PDFPage)将获得的坐标转换为适合注释的PDF坐标.
1> jksoegaard..:
最后,我通过创建扩展UIViewController和UIGestureRecognizerDelegate的PDFViewController类解决了这个问题.我添加了一个PDFView作为子视图,并将一个UIBarButtonItem添加到navigationItem,用于切换注释模式.
我在名为signingPath的UIBezierPath中记录触摸,并使用以下代码在currentAnnotation中使用类型PDFAnnotation的当前注释:
override func touchesBegan(_ touches: Set, 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, 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, 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
这真的是它的关键,因为这会禁用PDF上的滚动并使我能够接收触摸事件.
记录触摸事件并立即转换为PDFAnnotation的方式意味着在PDF上书写时注释是可见的,并且最终将其记录到PDF中的正确位置 - 无论滚动位置如何.
确保它最终出现在右页只是类似地将页面编号的硬编码0更改为pdfView.page(for:position,nearest:true)值.
2> 小智..:
我通过创建一个新的视图类(例如Annotate View)并在用户注释时放在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, 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
}
}