最近做項目遇到了這個需求,百度了一下發現還是12年的文章,使用了一下不好用,轉爲PDF後是空白的,開始Google查文件,現成功實現,效果如下圖
1.是我本地的viewcontroller上面的一個view。顯示一些請求的結果。可以用手勢簽名,等等巴拉巴拉的一堆
下面這個是轉的時候
然後是打開模擬器的文件夾的PDF文件,看看效果圖:
圖片可能有點大 對付看吧。
可能看着有點模糊,是因爲圖片的原因,一會說下在哪裏處理就行了。
準備工作:獲取要轉的image,圖1是一個view,首先我是給他轉成了一個圖片,轉成圖片有兩種方法,一個是view高度不超過屏幕的,一個是超過了屏幕的,我先都寫上吧:
+ (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;
}
在得到了image之後,要開始幹活了,首先,生成一個圖片,我要保存到本地,然後拿到他的URL,使用alassets這個框架
#import <AssetsLibrary/AssetsLibrary.h>
ProStrong ALAssetsLibrary *library;//將它定義爲屬性,原因下面寫了
#define kPadding 20
.
.
.
//上面一堆初始化各種方法的代碼不貼了
- (void)saveImage:(UIImage *)image{
//ALAssetsLibrary如果是臨時對象。執行完畢就會釋放 保存的aseturl就會失效,找不到目標圖片了,所以要聲明成屬性
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];
}];
}
保存完圖片後在回調內拿到存儲的URL。就是self.library這個對象將這個圖片存儲的地址,不能讓library是否,否則地址會失效
第二步:
-(void)turnSelfViewToPDF{
ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:self.saveImagePath
resultBlock:^(ALAsset *asset){
//根據URL取到圖片
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];
[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文件成功"];
}else{
[SVProgressHUD showMessage:@"生成PDF文件失敗"];
}
}
}
failureBlock:^(NSError *error) {
NSLog(@"從圖庫獲取圖片失敗: %@",error);
}];
}
- (void)setupPDFDocumentNamed:(NSString*)name width:(float)width height:(float)height {
//設置存儲的PDFframe,默認我傳的屏幕寬高,根據你的情況改變
_pageSize = CGSizeMake(width, height);
//根據傳進來的文件名字 創建文件夾,在內部存儲PDF文件
NSString *newPDFName = [NSString stringWithFormat:@"%@.pdf",name];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:newPDFName];
//開始繪製PDF
UIGraphicsBeginPDFContextToFile(pdfPath, CGRectZero, nil);
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, _pageSize.width, _pageSize.height), nil);
}
- (void)addImage:(UIImage*)image atPoint:(CGPoint)point {
//向PDF內添加圖片
CGRect imageFrame = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[image drawInRect:imageFrame];
UIGraphicsEndPDFContext();
}
以上就是基本的圖片轉PDF的方法,親測可用,效果槓槓的
其他:你的領導可能讓你在轉PDF的時候要給PDF潤色啦,加個title啦,加個題記,巴拉巴拉的,所以先寫一個在PDF文件最上方加title和一個紅色細線的方法,心急的朋友可略過此步驟:
- (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;
}
然後在這行文字下面加個醒目的線條:
- (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;
}
然後調用生成PDF的方法就會是這樣:
-(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];
//頂部添加title
CGRect textRect = [self addText:@"這裏是標題,呵呵呵呵呵呵" withFrame:CGRectMake(kPadding, kPadding, 400, 200) fontSize:48.0f];
//在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文件成功"];
}else{
[SVProgressHUD showMessage:@"生成PDF文件失敗"];
}
}
}
failureBlock:^(NSError *error) {
NSLog(@"從圖庫獲取圖片失敗: %@",error);
}];
}
最底部還可以調用addline的方法來添加線。不過要獲得image的y,可以改變addimage的方法的返回值讓他返回imageframe,然後把UIGraphicsEndPDFContext()拿到這裏來結束PDF生成即可。有不懂的留言問吧
demo正在做,做好了會更新文章放到github上。