Post

Replies

Boosts

Views

Activity

Reply to Drawing images to PDF in a loop, the first image is being drawn each time in iOS 15 only
I don't see how to edit my original question, so posting as an answer since I wanted to show better code samples. I was able to create a new project (objc, storyboard) and put the following code in the viewcontroller and replicate the issue: @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [self createPDF]; } -(void)drawPageNumbersOnPDFFile:(NSString *)pdfFile { NSURL *pdfUrl = [NSURL fileURLWithPath:pdfFile]; CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl); NSMutableData* data = [NSMutableData data]; UIGraphicsBeginPDFContextToData(data, CGRectZero, nil); int currentPage; int totalPages = 1; UIFont *font = [UIFont fontWithName:@"Helvetica" size:20]; for (size_t page = 1; page <= totalPages; page++) { // Get the current page and page frame CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdf, page); const CGRect pageFrame = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox); UIGraphicsBeginPDFPageWithInfo(pageFrame, nil); // Draw the page (flipped) CGContextRef ctx = UIGraphicsGetCurrentContext(); CGContextSaveGState(ctx); CGContextScaleCTM(ctx, 1, -1); CGContextTranslateCTM(ctx, 0, -pageFrame.size.height); CGContextDrawPDFPage(ctx, pdfPage); CGContextRestoreGState(ctx); // draw page number here currentPage = page; NSString *temp; temp = [NSString stringWithFormat:@"Page %d of %d",currentPage, totalPages]; UIGraphicsPushContext(ctx); [temp drawAtPoint:CGPointMake(0, 0) withAttributes:@{ NSFontAttributeName: font }]; UIGraphicsPopContext(); } UIGraphicsEndPDFContext(); CGPDFDocumentRelease(pdf); pdf = nil; [data writeToFile:pdfFile atomically:YES]; } - (void)createPDF { CGRect pageRect = CGRectMake(0, 0, 612, 792); NSString *filename = [self getFullPathForFile:@"Test.pdf"]; CGContextRef pdfContext = [self getPDFContextWithPageRect:pageRect andFilename:filename]; CGContextBeginPage (pdfContext, &pageRect); NSArray *imageNames = [NSArray arrayWithObjects:@"ImageX.png", @"ImageY.png", nil]; for (int i = 0; i < [imageNames count]; i++) { NSString *imageName = [imageNames objectAtIndex:i]; double y = i * 21; [self handleImage:imageName andY:y andPDFContext:pdfContext]; } CGContextEndPage (pdfContext); CGContextRelease (pdfContext); [self drawPageNumbersOnPDFFile:filename]; } -(void)handleImage:(NSString *)imageName andY:(CGFloat)y andPDFContext:(CGContextRef )pdfContext { UIImage *image = [UIImage imageNamed:imageName]; CGRect signatureRect = CGRectMake(238,y, 114, 28); CGContextDrawImage (pdfContext, signatureRect, image.CGImage); } -(NSString *)getFullPathForFile:(NSString *)fileName { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName]; return filePath; } -(CGContextRef)getPDFContextWithPageRect:(CGRect)pageRect andFilename:(NSString *)filename { // This code block sets up our PDF Context so that we can draw to it CGContextRef pdfContext; CFStringRef path; CFURLRef url; CFMutableDictionaryRef myDictionary = NULL; // Create a CFString from the filename we provide to this method when we call it path = CFStringCreateWithCString (NULL, [filename UTF8String], kCFStringEncodingUTF8); // Create a CFURL using the CFString we just defined url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, 0); CFRelease (path); // This dictionary contains extra options mostly for 'signing' the PDF myDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("My PDF File")); CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name")); // Create our PDF Context with the CFURL, the CGRect we provide, and the above defined dictionary pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary); // Cleanup our mess CFRelease(myDictionary); CFRelease(url); // Done creating our PDF Context, now it's time to draw to it return pdfContext; } @end Upon launching, it generates a file named Test.pdf in the documents folder. It should draw the two different images that I have attached which I included in the project. It should work with any images. The issue appears to be when drawPageNumbersOnPDFFile is called. Removing the call to this function generates a PDF with the two different images as expected. The reason for that function is because it was required that we have the page numbers at the bottom with the format 'Page 1 of 10', so we do it after all pages have been created so that we know the total page count. Not sure what in that function could be causing the change in the second image. Thanks
Oct ’21