项目需求APP连接打印机,打印出APP里加载的PDF文件或H5网页。以下mark打印功能的开发。
//点击打印 -(void)printAction:(UIBarButtonItem *)sender { if ([_url containsString:@".aspx"] || [_url containsString:@".html"]) { //打印H5网页 /** Safari自带共享按钮,包含打印功能,可跳出APP打印 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"打印网页需前往Safari浏览器,并点击顶部共享按钮,即可选择“打印”" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"立即前往" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:_url]]) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_url]]; } }]; [alertController addAction:action1]; [alertController addAction:action2]; [self presentViewController:alertController animated:YES completion:nil]; */ //直接弹出打印控制器打印网页 UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController]; //打印完成回调 void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) { if(!completed && error){ NSLog(@"FAILED! due to error in domain %@ with error code %ld", error.domain, (long)error.code); } }; //配置打印信息 UIPrintInfo *printInfo = [UIPrintInfo printInfo]; printInfo.outputType = UIPrintInfoOutputGeneral; //输出类型,可打印文本、图形、图像 printInfo.jobName = @"就医解读报告"; //打印工作标识 printInfo.duplex = UIPrintInfoDuplexLongEdge; //双面打印绕长边翻页,NONE为禁止双面 printController.printInfo = printInfo; printController.showsPageRange = YES; //格式化打印UIWebView上显示的内容 UIViewPrintFormatter *viewFormatter = [self.webView viewPrintFormatter]; viewFormatter.startPage = 0; printController.printFormatter = viewFormatter; /** 格式化打印HTML文档 UIMarkupTextPrintFormatter *htmlFormatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:self.htmlString]; htmlFormatter.startPage = 0; htmlFormatter.contentInsets = UIEdgeInsetsMake(72.0, 72.0, 72.0, 72.0); */ /** 格式化打印简单文字 UISimpleTextPrintFormatter *textFormatter = [[UISimpleTextPrintFormatter alloc] initWithText:@"嘛哩嘛哩哄发哈砂砾石"]; textFormatter.startPage = 0;//指定从哪一张开始打印0代表第一张 textFormatter.contentInsets = UIEdgeInsetsMake(36, 36, 36, 36);//72相当于1英寸,这样设置上下左右的边距都为0.5英寸 textFormatter.maximumContentWidth = 504;//(72x7.5)相当于打印宽度为7英寸 */ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { [printController presentFromBarButtonItem:sender animated:YES completionHandler:completionHandler]; //或者 presentFromRect:inView:animated:completionHandler: }else{ [printController presentAnimated:YES completionHandler:completionHandler]; } }else{ //打印网络加载的PDF文件 [MBProgressHUD showHUDAddedTo:self.view animated:YES]; //首先需要下载下来 [[HDNetworking sharedHDNetworking] downLoadWithURL:_url progress:nil destination:^NSURL * _Nullable(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) { //返回目的地路径 NSString *cashPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; return [NSURL fileURLWithPath:[cashPath stringByAppendingPathComponent:response.suggestedFilename]]; } downLoadSuccess:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath) { [MBProgressHUD hideHUDForView:self.view animated:YES]; DLog(@"response = %@, filePath = %@", response, filePath); _tempPath = filePath.path; //获取到本地文件路径 //方法一:文件预览控制器打印,其不仅有打印功能,而且有保存、转发等功能 self.previewController = [[QLPreviewController alloc] init]; self.previewController.dataSource = self; self.previewController.delegate = self; [self presentViewController:self.previewController animated:YES completion:nil]; //方法二:单纯用打印控制器打印PDF /* AirPrint可以直接打印一些内容。 这些内容是 NSData, NSURL, UIImage, and ALAsset 类的实例, 但是这些实例的内容, 或者引用的类型(NSURL)必须是 image 或者pdf. 对于 image来说, NSData, NSURL, UIImage, and ALAsset 类型都可以的。 对于PDF, 只能使用 NSData, NSURL。 然后需要将这些数据实例直接赋值 给 UIPrintInteractionController实例的 printingItem 或者 printingItems 属性。 */ /* UIPrintInteractionController *pic = [UIPrintInteractionController sharedPrintController]; NSData *pdfData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:_tempPath]]; if (pic && [UIPrintInteractionController canPrintData:pdfData]) { pic.delegate = self; UIPrintInfo *printInfo = [UIPrintInfo printInfo]; printInfo.outputType = UIPrintInfoOutputGeneral; printInfo.jobName = @"就医解读报告"; printInfo.duplex = UIPrintInfoDuplexLongEdge; pic.printInfo = printInfo; pic.showsPageRange = YES; pic.printingItem = pdfData; void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *pic, BOOL completed, NSError *error) { if (!completed && error) NSLog(@"FAILED! due to error in domain %@ with error code %ld", error.domain, error.code); }; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { [pic presentFromBarButtonItem:sender animated:YES completionHandler:completionHandler]; } else { [pic presentAnimated:YES completionHandler:completionHandler]; } } */ } failure:^(NSError * _Nonnull error) { [MBProgressHUD hideHUDForView:self.view animated:YES]; }]; } //内置Safari,功能较少 // SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:[NSURL URLWithString:_url]]; // [self presentViewController:safariVC animated:YES completion:nil]; }
#pragma QLPreViewDelegate - (NSInteger) numberOfPreviewItemsInPreviewController: (QLPreviewController *) controller { return 1; } - (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index { return [NSURL fileURLWithPath:_tempPath]; } - (void)previewControllerDidDismiss:(QLPreviewController *)controller { if(![_tempPath isEqual:@""]){ //文件预览器dismiss,将下载到本地的文件移除 NSFileManager * fileManager = [NSFileManager defaultManager]; [fileManager removeItemAtPath:_tempPath error:nil]; } }
注意,使用文件预览器需要导入框架<QuickLook/QuickLook.h>和代理QLPreviewControllerDelegate,QLPreviewControllerDataSource
根据项目需要,选择使用打印控制器还是文件预览器O(∩_∩)O~
//另附:UIActivityViewController、UIDocumentInteractionController的使用方法
//一、系统原生分享交互视图
//一、系统原生分享交互视图 /*! 1. 创建要分享的数据内容,加在一个数组 ActivityItems里。 */ NSString *textToShare = @"我是且行且珍惜_iOS,欢迎关注我!"; UIImage *imageToShare = [UIImage imageNamed:@"wang.png"]; NSURL *urlToShare = [NSURL URLWithString:@"https://github.com/wslcmk"]; NSArray *activityItems = @[urlToShare,textToShare,imageToShare]; //自定义 customActivity继承于UIActivity,创建自定义的Activity加在数组Activities中。 // customActivity * custom = [[customActivity alloc] initWithTitie:@"且行且珍惜_iOS" withActivityImage:[UIImage imageNamed:@"wang"] withUrl:urlToShare withType:@"customActivity" withShareContext:activityItems]; // NSArray *activities = @[custom]; /*! * 2.创建分享视图控制器,初始化UIActivityViewController * ActivityItems 在执行activity中用到的数据对象数组。数组中的对象类型是可变的,并依赖于应用程序管理的数据。例如,数据可能是由一个或者多个字符串/图像对象,代表了当前选中的内容。 * Activities 是一个UIActivity对象的数组,代表了应用程序支持的自定义服务。这个参数可以是nil。 */ NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@healthCare20160822163627HY2016.pdf",PER_REPORT_PATH]]; UIActivityViewController *activity = [[UIActivityViewController alloc] initWithActivityItems:@[@"分享PDF", url] applicationActivities:nil]; /*! 3、关闭系统的一些Activity类型,不需要的功能关掉。 */ //Activity 类型又分为“操作”和“分享”两大类 /* UIKIT_EXTERN NSString *const UIActivityTypePostToFacebook NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypePostToTwitter NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypePostToWeibo NS_AVAILABLE_IOS(6_0); //SinaWeibo UIKIT_EXTERN NSString *const UIActivityTypeMessage NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypeMail NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypePrint NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypeCopyToPasteboard NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypeAssignToContact NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypeSaveToCameraRoll NS_AVAILABLE_IOS(6_0); UIKIT_EXTERN NSString *const UIActivityTypeAddToReadingList NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIActivityTypePostToFlickr NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIActivityTypePostToVimeo NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIActivityTypePostToTencentWeibo NS_AVAILABLE_IOS(7_0); UIKIT_EXTERN NSString *const UIActivityTypeAirDrop NS_AVAILABLE_IOS(7_0); */ activity.excludedActivityTypes = @[UIActivityTypePostToVimeo]; [self presentViewController:activity animated:YES completion:nil];
二、文件交互控制器
@property(nonatomic,strong)UIDocumentInteractionController *docController;
//二、文件交互控制器 _docController = [UIDocumentInteractionController interactionControllerWithURL:[[NSBundle mainBundle] URLForResource:@"meinv" withExtension:@"gif"]]; //功能一:分享文件 // [_docController presentOpenInMenuFromRect:self.view.bounds inView:self.view animated:YES]; //展示更多可选项 // [_docController presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES]; //功能二:预览文件 //预览文件需遵循代理UIDocumentInteractionControllerDelegate // _docController.delegate = self; // [_docController presentPreviewAnimated:YES]; #pragma mark - UIDocumentInteractionControllerDelegate - (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller { return self; } - (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller { return self.view; } - (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller { return self.view.frame; }注意:UIDocumentInterRactionController定义的时候一定要是设置一个strong类型的属性,因为必须要对该对象进行持有;
当上述方法确实无法满足你的要求的时候就可以考虑一下用Quick Look了。