最近在做项目的时候,碰到这样一个需求,就是本地生成pdf文件,然后本地打开,经过测试发现,pdf文件是无法保存到相册里面的,只能存到手机里面,鉴于苹果的存储机制,需要取出来,进行本地展示,可以直接传到后台生成一个链接,直接在webview和浏览器里面打开,但是效果并不好,加载也慢些,所以就想到了用通过UIDocumentInteractionController来实现本地查看的操作,具体代码如下:
1,简介
UIDocumentInteractionController是从ios 3.2的sdk开始支持的,他是直接继承自NSObject,因此需要UIDocumentInteractionController提供的方法来展示他,UIDocumentInteractionController主要给我们提供了三种用途:
1 展示一个可以操作我们分享的文档类型的第三方App列表 2 在第一条展示列表的基础上添加额外的操作,比如复制,打印,预览,保存等。 3 结合Quick Look框架直接展示文档内容
2,简单的布局就不说了,直接上主要代码:
初始化:
- (IBAction)shareClick:(id)sender { UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:[[NSBundle mainBundle] URLForResource:@"MyFile" withExtension:@"pdf"]]; }
实现一个UIDocumentInteractionController的方法:
- (BOOL)presentOpenInMenuFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated;
在上面的button的点击方法里面再加入此方法:
UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:[[NSBundle mainBundle] URLForResource:@"MyFile" withExtension:@"pdf"]]; [documentController presentOpenInMenuFromRect:self.view.bounds inView:self.view animated:YES];
然后运行工程,进行测试,点击button,就可以看到如下界面:
这里我做了本地的汉化处理,真机上会显示汉字,具体请参考我写的“系统控件汉化”的博客。
简单介绍下这个界面:
第一行列表显示“AirDrop”是苹果在iOS 7
提供的一种跨设备分享的技术;
第二行列表展示整个iOS系统中,可以操作PDF文档的应用程序列表,还包括了苹果在iOS 8
提供的Share Extension
图标;
第三行列表展示现实设备可选的操作,如Copy
,Print
等;
这个时候,点击分享到微信,这个时候,会发现崩溃了,错误信息如下:
根据错误提示,“***has gone away prematurely”过早的消失,在ARC环境下,方法走完之后,UIDocumentInteractionController
的实例被释放了,展示出来的这个view是有Quick Look框架来操作,不会对UIDocumentInteractionController
产生引用,所以当点击button的时候,内部操作仍然会继续访问这个实例,所以就会报过早的消失这个错误!
解决方法:把UIDocumentInteractionController
声明为一个强指针strong类型的实例,然后修改下button的触发方法即可:
@property(nonatomic,strong)UIDocumentInteractionController *documentController;
方法写成私有方法:
-(void)presentOpenInMenu{ [_documentController presentOpenInMenuFromRect:self.view.bounds inView:self.view animated:YES];}
最终代码:
- (IBAction)shareClick:(id)sender { _documentController = [UIDocumentInteractionController interactionControllerWithURL:[[NSBundle mainBundle] URLForResource:@"MyFile" withExtension:@"pdf"]]; [self presentOpenInMenu]; }
这样就解决了!
展示可选操作,实现此方法即可:
- (BOOL)presentOptionsMenuFromRect:(CGRect)rect inView:(UIView *)view animated:(BOOL)animated;
封装私有方法:
-(void)presentOptionsMenus { [_documentController presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES]; }
然后在button点击方法里面替换成上述方法,效果如下图:
华丽丽的出现了!
直接预览
UIDocumentInteractionController
第三种预览文档内容的用途就是重点,而且也很常见,例如微信里面和浏览器里面就是用了此种方法,很是方便。
实现预览效果也很方便,实现一个代理方法即可:
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller;
此代理方法主要是用来指定UIDocumentInteractionController
要显示的视图所在的父视图,这样UIDocumentInteractionController
才知道在哪里展示Quick Look预览内容,当然了,这里是指定button所在的VC来做UIDocumentInteractionController
的代理对象,添加如下代码:
@interface ViewController ()<UIDocumentInteractionControllerDelegate>
_documentController.delegate = self;
实现代理方法:
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller { return self; }
UIDocumentInteractionController
是继承自NSObject
的,因而为了能够实现直接预览,我们需要用到UIDocumentInteractionController
提供的展示预览的方法:
- (BOOL)presentPreviewAnimated:(BOOL)animated;
私有方法:
-(void)presentPreview { [self.documentController presentPreviewAnimated:YES]; }
在button点点击事件里面添加上此方法即可,效果如下:
这样所要展示的pdf文件,就华丽丽的展示了出来!
参考自:http://www.jianshu.com/p/3f03897cf98a