Search code examples
iosswiftpdfios-pdfkitpdf-annotations

Can we get click or tap event and change color of PDFAnnotation with having image on it


I am trying to add pdfannotation inside pdfview with image only, where I need tap event of that particular iamge annotation that I have added. Can anyone suggest any way to achieve this. because I need specific tap or selected event of that. so after that I can able to change image color or any contents etc.

Currently I am using this as creating image inside PDFAnnotation.

`class ImageStampAnnotation: PDFAnnotation {

var image: UIImage!

// A custom init that sets the type to Stamp on default and assigns our Image variable
init(with image: UIImage!, forBounds bounds: CGRect, withProperties properties: [AnyHashable : Any]?) {
    super.init(bounds: bounds, forType: PDFAnnotationSubtype.stamp, withProperties: properties)
    
    self.image = image
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


override func draw(with box: PDFDisplayBox, in context: CGContext) {
    
    // Get the CGImage of our image
    guard let cgImage = self.image.cgImage else { return }
    
    // Draw our CGImage in the context of our PDFAnnotation bounds
    context.draw(cgImage, in: self.bounds)
    
}

}`

Adding tap gesture inside my viewDidLoad to pdfview to get tap area. And using tap gesture I am trying to fetch tapped event area to the nearest annotation.

` var annotations: [PDFAnnotation] = [] @objc func handleTap(_ sender: UITapGestureRecognizer) {

    guard sender.state == .ended else { return }

    let touchLocation = sender.location(in: pdfView)
    
    guard let page1 = pdfView!.page(for: touchLocation, nearest: true)
    else {
        return
    }
            
    // Convert the tap location to the PDF coordinate system
    let pdfPoint = pdfView.convert(touchLocation, to: page1)

    // Find the annotation at the tapped location
    let annotationsAtPoint = page1.annotation(at: pdfPoint)//page1!.annotations(at: pdfPoint)
    if let annotation = annotationsAtPoint,
       let index = annotations.firstIndex(of: annotation) {
        annotations[index].color = .red
        pdfView.setNeedsDisplay()
        print("Tapped on annotation at index \(index)")
        print(annotations[index].contents)
        print(annotations[index].fieldName)
        print(annotations[index].bounds)
    }

}`

Solution

  • I was able to do it with help of,

            NotificationCenter.default.addObserver(self, selector: #selector(notified(_:)), name: NSNotification.Name.PDFViewAnnotationHit, object: pdfView)
    

    Adding notification observer

        @objc private func notified(_ notification: Notification) {
        if let page = notification.object as? CustomPDFView {
            
            if let annotation = notification.userInfo!["PDFAnnotationHit"] as? ImageStampAnnotation {
                print("my custom image")
                print(annotation.contents)                
            }
        }
    }
    

    Also created custom pdf class to enable gesture.

    class CustomPDFView: PDFView {
    override func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    

    }