从Samples中入门IOS开发(三)------ 文档浏览
来源:互联网 发布:无损音乐论坛 知乎 编辑:程序博客网 时间:2024/04/27 22:51
IOS提供了对各种文档(PDF, PPT, word, txt, jpg等)的浏览功能,这个非常使用,因为我们难免需要app里浏览各种文档。官方的Sample code DocInteraction展示了如何在IOS浏览各种格式的文档。
本Sample非常简单,在tableview里列出了预定的和制定目录下的文档列表,点击某个文档时,能切换view并预览文档内容:
从这个sample里能学到的关键点是:
- 从文件目录中载入文件列表
- 监控文档目录中文件的变动,并实时反馈在UI上
- 预览各种文档内容
IOS提供了NSFileManager来访问文件系统,从以下代码能很清晰地了解到如何通过NSFileManager查询某个目录路径下所有所有文件:
- (void)directoryDidChange:(DirectoryWatcher *)folderWatcher{[self.documentURLs removeAllObjects]; // clear out the old docs and start overNSString *documentsDirectoryPath = [self applicationDocumentsDirectory];NSArray *documentsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:documentsDirectoryPath error:NULL]; for (NSString* curFileName in [documentsDirectoryContents objectEnumerator]){NSString *filePath = [documentsDirectoryPath stringByAppendingPathComponent:curFileName];NSURL *fileURL = [NSURL fileURLWithPath:filePath];BOOL isDirectory; [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory]; // proceed to add the document URL to our list (ignore the "Inbox" folder) if (!(isDirectory && [curFileName isEqualToString: @"Inbox"])) { [self.documentURLs addObject:fileURL]; }}[self.tableView reloadData];}在UI上展现文件列表就是通过tableView的datasource来完成,在上一节的分享中已分析此部分,此时只需reloadData刷新一下即可。
监控文档目录中文件的变动,并实时反馈在UI上
对文件目录的监控本例子是借助系统内核函数来完成,先看代码:
- (BOOL)startMonitoringDirectory:(NSString *)dirPath{// Double initializing is not going to work...if ((dirKQRef == NULL) && (dirFD == -1) && (kq == -1)){// Open the directory we're going to watchdirFD = open([dirPath fileSystemRepresentation], O_EVTONLY);if (dirFD >= 0){// Create a kqueue for our event messages...kq = kqueue();if (kq >= 0){struct kevent eventToAdd;eventToAdd.ident = dirFD;eventToAdd.filter = EVFILT_VNODE;eventToAdd.flags = EV_ADD | EV_CLEAR;eventToAdd.fflags = NOTE_WRITE;eventToAdd.data = 0;eventToAdd.udata = NULL;int errNum = kevent(kq, &eventToAdd, 1, NULL, 0, NULL);if (errNum == 0){CFFileDescriptorContext context = { 0, self, NULL, NULL, NULL };CFRunLoopSourceRef rls;// Passing true in the third argument so CFFileDescriptorInvalidate will close kq.dirKQRef = CFFileDescriptorCreate(NULL, kq, true, KQCallback, &context);if (dirKQRef != NULL){rls = CFFileDescriptorCreateRunLoopSource(NULL, dirKQRef, 0);if (rls != NULL){CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);CFRelease(rls);CFFileDescriptorEnableCallBacks(dirKQRef, kCFFileDescriptorReadCallBack);// If everything worked, return early and bypass shutting things downreturn YES;}// Couldn't create a runloop source, invalidate and release the CFFileDescriptorRefCFFileDescriptorInvalidate(dirKQRef); CFRelease(dirKQRef);dirKQRef = NULL;}}// kq is active, but something failed, close the handle...close(kq);kq = -1;}// file handle is open, but something failed, close the handle...close(dirFD);dirFD = -1;}}return NO;}
这段代码基本上都是对内核c函数的使用,虽然有些晦涩,但流程还是很简单的,首先是对系统事件的监控,然后基于IOS的thread框架来callback文件目录变动后的回调,回调的具体内容实现在KQCallback中,此方法也非常简单,实际上就是基于Delegate模式调用到上一段的directoryDidChange方法,继而刷新tableview的内容。具体的c函数的用法这里就不多说,但值得我们学习的是如何在IOS的层面上调用底层BSD系统API。
预览各种文档内容
本例子中最核心的点反而是最简单的,IOS提供了QLPreviewController,通过此controller能直接得到预览各种文档的view,你只需要把view塞到navigationController中即可,代码如下:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSURL *fileURL; if (indexPath.section == 0) { fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:documents[indexPath.row] ofType:nil]]; } else { fileURL = [self.documentURLs objectAtIndex:indexPath.row]; } [self setupDocumentControllerWithURL:fileURL]; [self.docInteractionController presentPreviewAnimated:YES]; QLPreviewController *previewController = [[QLPreviewController alloc] init]; previewController.dataSource = self; previewController.delegate = self; // start previewing the document at the current section index previewController.currentPreviewItemIndex = indexPath.row; [[self navigationController] pushViewController:previewController animated:YES]; [previewController release];}具体如何设定预览的内容和行为,是在QLPreviewControllerDelegate和QLPreviewControllerDataSource中完成的,所以这里只需要在controller中实现QLPreviewControllerDelegate和QLPreviewControllerDataSource相关方法即可:
// Returns the number of items that the preview controller should preview- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)previewController{ NSInteger numToPreview = 0; NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; if (selectedIndexPath.section == 0) numToPreview = NUM_DOCS; else numToPreview = self.documentURLs.count; return numToPreview;}// returns the item that the preview controller should preview- (id)previewController:(QLPreviewController *)previewController previewItemAtIndex:(NSInteger)idx{ NSURL *fileURL = nil; NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow]; if (selectedIndexPath.section == 0) { fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:documents[idx] ofType:nil]]; } else { fileURL = [self.documentURLs objectAtIndex:idx]; } return fileURL;}
第一个方法是设定一组文档浏览的个数,会影响到在文档预览中的上/下一页,第二个方法是指定文档预览的文件路径,由此可见在IOS中预览各种文档是件很简单的事儿,并且可预览的格式非常广,只要在mac的预览能支持的,这里都能支持,简单测试后发现基本能支持所有常规文档。
- 从Samples中入门IOS开发(三)------ 文档浏览
- 从Samples中入门IOS开发(六)------ Photo和Album浏览
- 从Samples中入门IOS开发(一)------ XCode上手
- 从Samples中入门IOS开发(二)------ CURD
- 从Samples中入门IOS开发(一)------ XCode上手
- 从Samples中入门IOS开发(四)------ 基于socket的网络编程
- 从Samples中入门IOS开发(五)------ 基于HTTP的网络编程
- 从Samples中入门IOS开发(四)------ 基于socket的网络编程
- 从Samples中入门IOS开发(四)------ 基于socket的网络编程
- 从Samples中入门IOS开发(五)------ 基于HTTP的网络编程
- iOS开发入门文档
- ios 入门开发三
- 从菜鸟到入门(三)- 文档撰写
- Android开发从入门到精通教程(技术文档)
- iOS中多种格式文档的查看浏览
- arcgis api for flex 开发入门(三)地图浏览控件的使用
- arcgis api for flex 开发入门(三)地图浏览控件的使用
- 基础教程2——Start Developing iOS Apps Today——从今天开始开发IOS(IOS7版)系列源文档翻译(三)
- Mysql数据事务隔离级别测试
- fedora14下运行程序出现GLib- GIO:ERROR:gdbusconnection.c:2270:initable_init: assertion failed: (connection->
- 显示时钟的JavaScript源码
- 程序中调用一个可执行文件,防止小部分程序down掉导致整个程序down掉
- HDU 2815 离散对数
- 从Samples中入门IOS开发(三)------ 文档浏览
- Linux-2.6平台下SCSI子系统初始化及退出
- MFC 获得当前exe文件的路径
- python 装饰器
- c#中从string数组转换到int数组
- Tomcat 7 HTTP 连接器(一)
- UNIX Shell控制结构—IF
- 80x86寻址模式
- 【大话设计模式】笔记——开放封闭原则