iOS - How to overwrite a single page of PDF files?
Very similar :Merge PDF files on iOS
It's not possible to reopen and continue editing a PDF file . Only read and redraw whole PDF again .
Cannot add image and save to pdf file using PDFKit
I have to also draw that image on PDFPage
to make them appear in the saved pdf file
final private class ImagePDFPage: PDFPage {
/// A flag indicates whether to draw image on a page
///
/// - Note: Set this to `true` before write pdf to file otherwise the image will not be appeared in pdf file
var saveImageToPDF: Bool = false
private var imageAnnotation: EkoPDFImageAnnotation? = nil
func addImageAnnotation(_ annotation: EkoPDFImageAnnotation) {
imageAnnotation = annotation
addAnnotation(annotation)
}
func removeImageAnnotation() {
guard let imageAnnotation = imageAnnotation else { return }
self.imageAnnotation = nil
removeAnnotation(imageAnnotation)
}
override func draw(with box: PDFDisplayBox, to context: CGContext) {
super.draw(with: box, to: context)
guard saveImageToPDF,
let annotation = imageAnnotation,
let cgImage = annotation.image?.cgImage else { return }
context.draw(cgImage, in: annotation.bounds)
}
}
and update PDFDocument.delegate
to tell to use ImagePDFPage
as a class for pdf page
extension PDFEditorViewController: PDFDocumentDelegate {
func classForPage() -> AnyClass {
return ImagePDFPage.self
}
}
The result
How can I lower memory climb when generating large PDF's
In general, memory is finite and your generated output isn't, so the way to make it work is to ensure that:
- you're not accumulating the entire PDF in memory as you generate it
- you're not unnecessarily keeping around byproducts of the rendering for each page
In your case, using UIGraphicsBeginPDFContextToData
means that you're rendering the whole PDF to an ever-expanding NSData. When that data gets too big, you'll get killed. Instead, try UIGraphicsBeginPDFContextToFile
. Also in your inner loop for rendering pages, consider inserting an @autoreleasepool { ... }
block to prevent objects from building up unnecessarily during a long run. I'm not sure how big your pagesArray
bunch of stuff actually is, and whether that's something you might consider "paging in" one page at a time as you generate.
Create PDF file with BIG html CODE
Try taking a look at this: https://pdfmerger.codeplex.com/
Then, divide the html, render each part into a separate file, and then merge them afterwards..
Create dynamic pdf documents on iOS
To draw some text in our PDF, we’re going to need to use the Core Text framework. To do this, select the project target and go to the Build Phases tab. Click the + sign below the Link Binaries With Libraries option, and then select the CoreText framework.
Then open ViewController.h and import the CoreText header:
#import <CoreText/CoreText.h>
Add a new method to ViewController.m to create a “hello world” PDF.
-(void)drawText
{
NSString* fileName = @"Invoice.PDF";
NSArray *arrayPaths =
NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *path = [arrayPaths objectAtIndex:0];
NSString* pdfFileName = [path stringByAppendingPathComponent:fileName];
NSString* textToDraw = @"Hello World";
CFStringRef stringRef = (__bridge CFStringRef)textToDraw;
// Prepare the text using a Core Text Framesetter.
CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, NULL);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);
CGRect frameRect = CGRectMake(0, 0, 300, 50);
CGMutablePathRef framePath = CGPathCreateMutable();
CGPathAddRect(framePath, NULL, frameRect);
// Get the frame that will do the rendering.
CFRange currentRange = CFRangeMake(0, 0);
CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
CGPathRelease(framePath);
// Create the PDF context using the default page size of 612 x 792.
UIGraphicsBeginPDFContextToFile(pdfFileName, CGRectZero, nil);
// Mark the beginning of a new page.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);
// Get the graphics context.
CGContextRef currentContext = UIGraphicsGetCurrentContext();
// Put the text matrix into a known state. This ensures
// that no old scaling factors are left in place.
CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);
// Core Text draws from the bottom-left corner up, so flip
// the current transform prior to drawing.
CGContextTranslateCTM(currentContext, 0, 100);
CGContextScaleCTM(currentContext, 1.0, -1.0);
// Draw the frame.
CTFrameDraw(frameRef, currentContext);
CFRelease(frameRef);
CFRelease(stringRef);
CFRelease(framesetter);
// Close the PDF context and write the contents out.
UIGraphicsEndPDFContext();
}
References
1. How to create a pdf with quartz-2d in ios part-1
2. How to create a pdf with quartz 2d in ios part-2
For More on CoreText framework
1. Core text tutorial for ios making a magazine app
2. About Core Text - Apple Doc
when export to pdf i got extra one empty page
I suspect that one of your images is too large, but without access to the images I can't tell for sure. I created three images with SF Symbols and played with resizing the images. I can create the problem by setting the images too large.
let images = [NSImage(systemSymbolName: "xmark", accessibilityDescription: "xmark")!,
NSImage(systemSymbolName: "pencil.slash", accessibilityDescription: "pencil")!,
NSImage(systemSymbolName: "pencil.and.outline", accessibilityDescription: "pencil")!]
let document = PDFDocument(format: .a4)
document.add(.footerLeft, textObject: PDFSimpleText(text: "Generated from Pdf Scanner"))
for eachImage in images {
// eachImage.size = NSSize(width: 400, height: 380)
// above works
eachImage.size = NSSize(width: 790, height: 760)
let imageElement = PDFImage(image: eachImage)
imageElement.sizeFit = .height
document.add(.contentCenter ,image: imageElement)
}
let generator = PDFGenerator(document: document)
generator.debug = true
let pdfUrl = (try? generator.generateURL(filename: "Example.pdf"))!
print("pdf location: \(pdfUrl)")
Note: generator.debug = true
might be useful.
PDF specification for appending
As others have already mentioned, merging two PDF files together will be a large undertaking, if you don't use a PDF library. You will need a solid understanding of the internal PDF structure. Here is a link to the PDF specification. It's a good place to get started - PDF Reference.
Before I go into detail, here is a little experiment in merging two very simple PDF files, and the result. The two files are 34kb each. The resulting file was 35kb, and it contained the pages of each of the input files. That alone shows that there is more going on under the hood than merging the code for the two input documents. Comparing the code for the input and output documents, also showed that they have been completely re-created, with different object IDs for each object.
A usual PDF document contains a header, body, cross-reference table and a trailer.
When a PDF document is read, the library starts from the top, and then jumps to the end of the document, moving back, until it hits the cross-reference table. In this table, the library looks for the objects, and byte offsets in a particular document. This table is updated, or re-created when new objects are added to the document.
To merge two documents manually, you will have to move the objects from the body of the second document into the first document. Then you can update the metadata of the first document if necessary. The difficult task here is updating, and possibly re-creating the cross-reference table. You will need to implement a significant portion of the PDF spec to be able to do that.
If you decide to use a library in your project, there are some fairly lightweight libraries out there that will do the trick. The PDFtk library is fairly lightweight, and can do PDF merging with 1 command. It has a free version, as well as command line capabilities. You should be able to set up a simple server to host it in your environment, and then call it via Java Script.
In case your project requires more than a free library, then there is APDFL, which is a commercial PDF processing library. It has a .NET or a Java interface, so you can easily create a server app that will merge PDF files for you.
Related Topics
Swift String Escaping When Serializing to JSON Using Codable
Font Size on Universal Storyboard
How to Remove All References for Outlet
Xcode 10 Not Being Able to Archive Project
Done Button Event Mpmovieplayercontroller
How to Dynamically Add Rows to a Specific Uitableview Section
Are Storyboards Going to Work on iOS 4
Uiimageview Not Showing Transparency of Png Images from Uiimagepickercontroller
Error Setting Text in Collection View Cell
Swift - "Use of Unresolved Identifier"
"Could Not Inspect Application Package" Xcode
Is Wkwebview Designed as a Replacement of Uiwebview
Possible to Send Automated Email
Swift - the Data Couldn't Be Read Because It Isn't in the Correct Format
How to Get Touchid Information and Compare to a Fingerprint Database
Application Is "Ready to Sale" But Not Reflected on Itunes Store