從Samples中入門IOS開發(三)—— 文檔瀏覽

來源:互聯網
上載者:User

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的預覽能支援的,這裡都能支援,簡單測試後發現基本能支援所有常規文檔。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.