我想從任何UIDocumentInteractionController的supported file types的攔截點擊和在一個模態的視圖(由UIDocumentInteractionController的presentPreviewAnimated:
方法提供)顯示它們。此模式視圖還提供了「打開在...」功能,可在設備上的其他兼容應用程序中打開這些文檔中的任何一個。下面的代碼將攔截這些點擊,檢測URL字符串是否具有任何適當的後綴,加載此數據,將其寫入目錄,再次讀取並最終使用presentPreviewAnimated:
方法中的數據。我必須首先將數據寫入文件系統,因爲UIDocumentInteractionController需要本地數據,並且不能直接從URL使用數據(據我所知)。使用UIDocumentInteractionController顯示presentPreviewAnimated:經由的UIWebView
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
ILog(@"URL loading for NavigationTypeLinkClicked: %@", request.URL.absoluteString);
if ([request.URL.absoluteString hasSuffix:@"pdf"] || [request.URL.absoluteString hasSuffix:@"doc"] || [request.URL.absoluteString hasSuffix:@"xls"] || [request.URL.absoluteString hasSuffix:@"ppt"] || [request.URL.absoluteString hasSuffix:@"rtf"] || [request.URL.absoluteString hasSuffix:@"key"] || [request.URL.absoluteString hasSuffix:@"numbers"] || [request.URL.absoluteString hasSuffix:@"pages"]) {
if (NSClassFromString(@"UIDocumentInteractionController")) {
NSArray *parts = [request.URL.absoluteString componentsSeparatedByString:@"/"];
self.previewDocumentFileName = [parts lastObject];
NSLog(@"The file name is %@", previewDocumentFileName);
// Get file online
NSData *fileOnline = [[NSData alloc] initWithContentsOfURL:request.URL];
// Write file to the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if (!documentsDirectory) {NSLog(@"Documents directory not found!");}
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:previewDocumentFileName];
[fileOnline writeToFile:appFile atomically:YES];
NSLog(@"Resource file '%@' has been written to the Documents directory from online", previewDocumentFileName);
[fileOnline release];
// Get file again from Documents directory
NSURL *fileURL = [NSURL fileURLWithPath:appFile];
UIDocumentInteractionController* docController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
docController.delegate = self;
[docController retain];
BOOL result = [docController presentPreviewAnimated:YES];
if (!result) {
[docController release];
}
return NO;
}
}
}
// Do lots of other URL-detecting stuff here
}
我也實現以下委託方法使用適當的視圖,並刪除該文件的觀點已經被駁回後(previewDocumentFileName
是一個類變量):
#pragma mark -
#pragma mark Document Interaction Controller Delegate Methods
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {
return self;
}
- (void)documentInteractionControllerDidEndPreview:(UIDocumentInteractionController *)controller {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:previewDocumentFileName];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:appFile error:NULL];
//[controller release]; // Release here was causing crashes
}
請注意,蘋果文檔中特別提到了文檔控制器需要手動保留的事實,所以我這樣做了。我也需要被釋放,所以如果控制器沒有被使用(頂端方法)並試圖在它被使用之後釋放它(委託方法),但是那個版本導致崩潰,所以我刪除它並且看起來似乎從這個角度來說工作得很好。
以背景爲例,我的問題與這樣一個事實有關,儘管此代碼似乎在iPhone模擬器中工作(聯機文檔在presentPreviewAnimated:
視圖中正確顯示,儘管沒有「打開」 ..'對話,不能在SIM卡中使用),它不會在iPad上顯示presentPreviewMethod:
或我的真實iPhone或iPad設備。我相信該方法被正確調用,但presentPreviewAnimated:
方法正在返回NO
,這意味着它無法顯示文檔預覽。
這是爲什麼?我是不是正確保存文件(因此它不會被檢測爲* pdf或* doc等)?我還能做什麼錯?除了Apple文檔之外,還有很少的文檔或示例代碼,所以我希望至少這個代碼對某個人有幫助,儘管我希望首先讓它工作100%。提前致謝。
''[docController release]':打開鐺。您應該發現由於您不擁有控制器而產生警告。 – jww 2011-04-01 10:44:48
'[controller release];' - 這會導致崩潰,因爲您不對此對象負責。它在參數中爲您提供。您尚未分配它才能釋放它。 – 2011-11-17 21:40:56
它對我來說工作正常。 謝謝瑞奇 – 2013-11-19 10:52:28