Recently, I met this requirement when I was working on a project. After searching on Baidu, I found that it was still an article of 2012, but it did not work well after I used it for a while. After converting it to PDF, it was blank

1. Is a view on my local ViewController. Displays the results of some requests. You can sign with your hands, blah, blah, blah, blah


This one down here is when it turns


Then open the PDF file in the emulator folder and look at the renderings:

Pictures can be a bit of a struggle.

Maybe it looks a little blurry because of the picture, but I’ll talk about where to process it later.

Figure 1 is a view. First, I converted it into an image. There are two ways to convert an image, one is for a view whose height does not exceed the screen, and the other is for a view whose height exceeds the screen.

+ (UIImage *) snapshotWithScrollView:(UIScrollView *)scrollView{
        UIImage* image = nil;
        UIGraphicsBeginImageContext(scrollView.contentSize);
        {
                CGPoint savedContentOffset = scrollView.contentOffset;
                CGRect savedFrame = scrollView.frame;
                scrollView.contentOffset = CGPointZero;
                scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
                
                [scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
                image = UIGraphicsGetImageFromCurrentImageContext();
                
                scrollView.contentOffset = savedContentOffset;
                scrollView.frame = savedFrame;
            }
        UIGraphicsEndImageContext();
        
        if(image ! = nil) {return image;
            }
        return nil;
}

+ (UIImage *)snapshotWithView:(UIView *)view
{
        CGSize size = view.bounds.size;
        UIGraphicsBeginImageContextWithOptions(size, YES, 0);
        [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return image;
}
Copy the code


Now that I’ve got the image, I’m going to do the work. First, I’m going to generate an image, I’m going to save it locally, and then I’m going to get its URL and I’m going to use the alAssets framework

#import <AssetsLibrary/AssetsLibrary.h>ProStrong ALAssetsLibrary *library; // Define it as an attribute, for reasons described below#define kPadding 20- (void)saveImage:(UIImage *)image{//ALAssetsLibrary if it is temporary. Library = [[ALAssetsLibrary alloc] init]; self.library = [ALAssetsLibrary alloc] init]; [self.library writeImageToSavedPhotosAlbum:image.CGImage metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) { NSLog(@"assetURL = %@, error = %@", assetURL, error);
        self.saveImagePath = assetURL;
        [self turnSelfViewToPDF];
    }];
}Copy the code

After saving the image, retrieve the stored URL in the callback. Library is the address at which the image is stored. Library cannot be called, or the address will be invalidated


The second step:

-(void)turnSelfViewToPDF{ ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init]; [assetslibrary assetForURL: self saveImagePath resultBlock: ^ (ALAsset * asset) {/ / ALAssetRepresentation * rep = according to the URL to get pictures [asset defaultRepresentation]; CGImageRef iref = [rep fullScreenImage];if (iref) {
                           UIImage *image = [UIImage imageWithCGImage:iref];
                           [self setupPDFDocumentNamed:self.recordId width:screenWidth height:self.bgScrollView.contentSize.height];
                           [self addImage:image
                                                     atPoint:CGPointMake((_pageSize.width/2)-(image.size.width/2), kPadding)];
                           
                           NSFileManager *manager = [NSFileManager defaultManager];
                           NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
                           NSString *path = [paths lastObject];
                           NSString * path1 = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",self.recordId]];
                           if ([manager fileExistsAtPath:path1]) {
                               [SVProgressHUD showMessage:@"PDF file generated successfully"];
                           }else{
                               [SVProgressHUD showMessage:@"Failed to generate PDF file"];
                           }
                       }
                   }
                  failureBlock:^(NSError *error) {
                      NSLog(@"Failed to get image from gallery: %@",error);
                  }];
}

- (void)setupPDFDocumentNamed:(NSString*)name width:(float)width height:(float_pageSize = CGSizeMake(width, height); _pageSize = CGSizeMake(width, height); NSString *newPDFName = [NSString stringWithFormat:@"%@.pdf",name]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:newPDFName]; / / start drawing PDF UIGraphicsBeginPDFContextToFile (pdfPath CGRectZero, nil); UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, _pageSize.width, _pageSize.height), nil); } - (void)addImage:(UIImage*)image atPoint:(CGPoint)point { point.y, image.size.width, image.size.height); [image drawInRect:imageFrame]; UIGraphicsEndPDFContext(); }Copy the code


Above is the basic picture to PDF method, pro test available, the effect of leverage

Other: your leader may ask you to edit the PDF, add a title, add a caption, blah, blah, so first write a way to add the title and a red line at the top of the PDF file, impatient friends can skip this step:

- (CGRect)addText:(NSString*)text withFrame:(CGRect)frame fontSize:(float)fontSize {
    UIFont *font = [UIFont systemFontOfSize:fontSize];
    NSMutableParagraphStyle *style1 = [NSMutableParagraphStyle new];
    style1.lineBreakMode = NSLineBreakByWordWrapping;
    CGSize stringSize = [text boundingRectWithSize:_pageSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSParagraphStyleAttributeName:style1} context:nil].size;
    
    float textWidth = frame.size.width;
    
    if (textWidth < stringSize.width)
        textWidth = stringSize.width;
    if (textWidth > _pageSize.width)
        textWidth = _pageSize.width - frame.origin.x;
    CGRect renderingRect = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);
    NSMutableParagraphStyle *style = [NSMutableParagraphStyle new];
    style.lineBreakMode = NSLineBreakByWordWrapping;
    style.alignment = NSTextAlignmentLeft;
    [text drawInRect:renderingRect withAttributes:@{NSFontAttributeName:font,NSParagraphStyleAttributeName:style}];
    frame = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);
    return frame;
}Copy the code

Then add a bold line under the line:

-  (CGRect)addLineWithFrame:(CGRect)frame withColor:(UIColor*)color {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(currentContext, color.CGColor);
    CGContextSetLineWidth(currentContext, frame.size.height);
    CGPoint startPoint = frame.origin;
    CGPoint endPoint = CGPointMake(frame.origin.x + frame.size.width, frame.origin.y);
    CGContextBeginPath(currentContext);
    CGContextMoveToPoint(currentContext, startPoint.x, startPoint.y);
    CGContextAddLineToPoint(currentContext, endPoint.x, endPoint.y);
    CGContextClosePath(currentContext);
    CGContextDrawPath(currentContext, kCGPathFillStroke);
    return frame;
}Copy the code

Then calling the method that generated the PDF would look like this:

-(void)turnSelfViewToPDF{
    ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
    [assetslibrary assetForURL:self.saveImagePath
                   resultBlock:^(ALAsset *asset){
                       ALAssetRepresentation *rep = [asset defaultRepresentation];
                       CGImageRef iref = [rep fullScreenImage];
                       if(iref) { UIImage *image = [UIImage imageWithCGImage:iref]; [self setupPDFDocumentNamed:self.recordId width:screenWidth height:self.bgScrollView.contentSize.height]; // Add title CGRect textRect = [self addText:@"Here's the headline, hehe hehe hehe."WithFrame :CGRectMake(kPadding, kPadding, 400, 200) fontSize:48.0f]; Draw a line under the / / in the title CGRect blueLineRect = [self addLineWithFrame: CGRectMake (kPadding, textRect.origin.y + textRect.size.height + kPadding, _pageSize.width - kPadding*2, 4) withColor:[UIColor blueColor]]; [self addImage:anImage atPoint:CGPointMake((_pagesize.width /2)-(animage.size. Width /2)), blueLineRect.origin.y + blueLineRect.size.height + kPadding)] NSFileManager *manager = [NSFileManager defaultManager]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString *path = [paths lastObject]; NSString * path1 = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",self.recordId]];
                           if ([manager fileExistsAtPath:path1]) {
                               [SVProgressHUD showMessage:@"PDF file generated successfully"];
                           }else{
                               [SVProgressHUD showMessage:@"Failed to generate PDF file"];
                           }
                       }
                   }
                  failureBlock:^(NSError *error) {
                      NSLog(@"Failed to get image from gallery: %@",error);
                  }];
}
Copy the code

At the bottom, you can also call the addline method to add lines. But to get the y of the image, you can change the return value of Addimage’s method to return imageFrame, and then put UIGraphicsEndPDFContext() here to finish the PDF generation. If you don’t understand the message, ask

Demo link: github.com/littleZhang…