3

I'm fairly new to Swift programming and I've created an app for work to simplify a task where I programmatically fill-in fields on an existing PDF. I've captured a signature as a UIImage and I'd like to add this to the PDF as an annotation like the rest of the fields. Is this possible?

// Annotate Signature
let signatureFieldBounds = CGRect(x:390, y:142, width:100, height:30)
let signatureField = PDFAnnotation(bounds: signatureFieldBounds, forType: .stamp, withProperties: nil)
signatureField.fieldName = FieldNames.signature.rawValue
signatureField.backgroundColor = UIColor.clear
sigImage?.draw(in: signatureFieldBounds)

page.addAnnotation(signatureField)

I've also tried: signatureField.stampName = sigImage as! UIImage instead of the draw function but this gives the error 'Cannot assign value of type 'UIImage' to type 'String?''

The screenshot shows what I get annotated: screenshot

Any help at all would be greatly appreciated!!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Marcus
  • 31
  • 1
  • 5

1 Answers1

4

This was tricky for me too, but I figured it out.

Create a custom PDFAnnotation, then override the draw method to draw the image in the pdf context.

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)

 } 
}

Then, just add it to the document

guard let signatureImage = signatureImage, let page = pdfContainerView.currentPage else { return }
    let pageBounds = page.bounds(for: .cropBox)
    let imageBounds = CGRect(x: pageBounds.midX, y: pageBounds.midY, width: 200, height: 100)
    let imageStamp = ImageStampAnnotation(with: signatureImage, forBounds: imageBounds, withProperties: nil)
    page.addAnnotation(imageStamp)

I wrote a medium article on how I did it, added a gesture recognizer to it and a canvas to grab a signature: https://medium.com/@rajejones/add-a-signature-to-pdf-using-pdfkit-with-swift-7f13f7faad3e

Rajee Jones
  • 289
  • 2
  • 9
  • Thank you so much for that Rajee! That is exactly what I needed, it worked perfectly! I was halfway there with this with the 'Stamp' subtype but I was having trouble setting up the context. Thank you again, it's VERY much appreciated! – Marcus Mar 18 '18 at 09:53
  • 1
    Not working couldn't draw signature. can you please check this ? @Rajee – Mohamed Raffi May 29 '18 at 18:30
  • not working and i tried to pass cgpoints through which the image was created but i am getting that upside down – Mohammad Yunus Dec 16 '19 at 19:06