使用 QuickLook 进行全屏文件预览

原文: http://www.cimgf.com/2012/07/11/a-better-fullscreen-asset-viewer-with-quicklook/

从去年开始,我有许多时间是为医疗设备公司编写 iPad 应用。这些公司想用iPad 杰出的展示效果向潜在买家展示他们的销售记录或电子资料。这无可非议。尤其是第3代 iPad 的视网膜屏,具有不可抗拒的吸引力。

此前我们一直在 UIWebView 中显示这些文件,它支持许多文件格式。幸亏有这种简单的处理方式,要不然就麻烦了。

这个办法很有效,但随后应用程序会变得迟缓,并暴露出一些可用性问题。对于需要直接面对大量用户的app来说这尤其致命。程序需要改进。为了全屏,我们用模式窗口的方式加载了一个全屏的view controller。问题是这只能支持横屏。由于某些原因,如果我们让它在某些时候支持两个方向而其他时候仅支持横屏,它不太稳定(工程师会说,“呃,我不知道”)。它总是有一个无法被隐藏的导航栏,用户在滚动文档内容时总能看到它。而且,无法直接跳到文档中的某一页。如果你想到达第325页,你必须一页页滚动,一直滚到第325页。这个体验差极了,相信没有任何用户会用它来查看大文档。这些问题我都没有任何好的解决办法。

但在一个程序中,我被要求添加一个“Open In...”按钮,允许用户用Keynote 打开 Keynote 文档。在实现过程中,我知道 QuickLook 有一个默认的“Open In...”选项,提供简单但自动全屏的窗口。我们可以用QuickLook 来实现文档预览。在下面的截图中,左边是最初的预览窗口,右边是 QuickLook 预览窗口,你可以发现二者的不同。

使用 QuickLook 进行全屏文件预览_第1张图片

注意,当用户滚动时导航条会消失。用户可以通过右边的缩略图小图标直接跳到某一页。窗口是完全全屏的(除非文档的内容不满一屏)。

使用 QuickLook 的另一个好处,是两个方向都能支持,你可以看下图的竖屏效果:

使用 QuickLook 进行全屏文件预览_第2张图片

使用 QuickLook preview controller 时,位于右上角的action 按钮消失了——对于这个组件,不同的公司可能会有不同的需求。一个公司想要一个“Open In...”按钮,以便打开 Keynote 文档,而另一个公司则根本不想提供任何导出/编辑功能。对于Office 或者 iWork 文档这当然会成为问题,但对于 PDF 这样的文档,它完全是只读的,这个公司根本不想让用户去编辑它。他们想尽可能的保证文档的版本是最新的,并且任何人不经许可不得篡改。

如果你使用 UIDocumentInteractionController来加载 QuickLook preview,你会获得一个 action 按钮,用户通过它来处理文档。标准的UIDocumentInteractionController 实现会在action 按钮上弹出一个选项菜单,如下图所示:

使用 QuickLook 进行全屏文件预览_第3张图片

如图中所示,你可以用 iBooks 或任何设备中支持这个文档格式的程序来打开文档,或者打印文档。我的第2个客户不想要这个菜单,因此最终我们决定不使用UIDocumentInteractionController 而是自己实现一个 QLPreviewController 子类。我们不得不重载-viewWillAppear:方法并从 navigation bar 中移除 right button。注意:iOS 6 更新这个办法在 iOS 6.0 中不再有效。我向苹果提到过这个问题,他们只是简单地回答他们不再支持这种做法并认为这是私有API。如果你想更加灵活地使用这些API,同时又能重载某些行为,可以向苹果提交bug报告。

// Header

#import <QuickLook/QuickLook.h>  

@interface MLQuickLookPreviewController : QLPreviewController  

@end  

// Implementation

@implementation MLQuickLookPreviewController  

- (void)viewWillAppear:(BOOL)animated {

   [super viewWillAppear:animated];

   [[self navigationItem] setRightBarButtonItem:nil animated:NO];

}  

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

   return YES;

}  

@end

在 -shouldAutorotateToInterfaceOrientation:方法中我们支持了所有的方向。这正是我们想要的,QuickLook preview controller 实现了客户想要的全屏,同时隐藏了“导出”或“编辑”功能,不管在竖向还是横向模式下都能进行页面导航。

当然,要使用 QLPreviewController,必须加入QuickLook.framework 框架到项目中。然后在源文件中导入<QuickLook/QuickLook.h>头文件,如上述代码中所示。你可以这样实现预览窗口的定制:

- (void)presentFullscreen {

   MLQuickLookPreviewController *previewer = [[MLQuickLookPreviewController alloc] init];

   [previewer setDataSource:self];

   [previewer setCurrentPreviewItemIndex:0];

   [self presentModalViewController:previewer animated:YES];

}

注意,数据源被设置为self。也就是说类必须实现QLPreviewControllerDataSource 方法。同时在类的头文件中,需要如下声明:

@interface MLDetailViewController : UIViewController <QLPreviewControllerDataSource>  

@end

在实现文件中,需要实现两个方法:

#pragma mark - #pragma mark QLPreviewControllerDataSource

- (NSInteger)numberOfPreviewItemsInPreviewController:

(QLPreviewController*)controller  {

   return ([self asset]) ? 1 : 0;

}  

- (id<QLPreviewItem>)previewController:(QLPreviewController*)

controller previewItemAtIndex:(NSInteger)index  {

   NSString *path = [[self asset] pathOnDiskAtCachePath:CACH_PATH];

   return [NSURL fileURLWithPath:path];

}

同时,你应该提供一个用于显示的文件列表。但在本例中,我们仅仅显示一个文件。所以我会判断 asset 是否为 nil,如果为 nil 返回 0,否则返回 1,以此来作为要预览的文档数。当 previewItemAtIndex方法被调用时,我返回一个文件 URL 地址,指向某个文件路径。这就是我们需要编写的全部代码。这将在 iPad 上显示一个美观而又实用的文档预览窗口。

结论

 

在项目越临近交付的时候,程序中的某些瑕疵就越发显得显眼。在 iPad 上,外观是极其重要的,对某些界面进行细微的调节即能大幅提升用户对app 的满意度。耶稣说,“去照样做”。再见。


你可能感兴趣的:(使用 QuickLook 进行全屏文件预览)