使用UIDocumentInteractionController和QLPreviewController預(yù)覽文件


引言:iOS對(duì)瀏覽文件提供了方便的SDK,讓開(kāi)發(fā)者調(diào)用實(shí)現(xiàn)各自的需求,之前利用UIWebView直接加載本地或者網(wǎng)絡(luò)路徑瀏覽文件薄货。最近研究了一下UIDocumentInteractionController和QLPreviewController去預(yù)覽文件,個(gè)人感覺(jué)各自有各自的優(yōu)缺點(diǎn),需要根據(jù)具體的業(yè)務(wù)場(chǎng)景選擇適合的方式蝇狼。


UIDocumentInteractionController的使用方法,以及QuickLook的使用方法倡怎,網(wǎng)上資料已經(jīng)很多了迅耘,這里記錄一下自己學(xué)習(xí)所獲得的知識(shí),和一個(gè)自定義的問(wèn)題监署。
一颤专、是否可以在線預(yù)覽
剛開(kāi)始接觸時(shí)的想法是:是否有在線預(yù)覽功能,UIDocumentInteractionController和QLPreviewController的顯示樣式自帶分頁(yè)效果钠乏,效果看起來(lái)和專(zhuān)業(yè)做文檔預(yù)覽的軟件栖秕,預(yù)覽效果類(lèi)似,那不是太好了晓避!然而現(xiàn)實(shí)很骨感簇捍,查閱了大量資料以及自己測(cè)試之后,我可以確定的答案是:不能在線預(yù)覽俏拱!只能加載本地文件暑塑。
二、UIDocumentInteractionController
使用過(guò)UIDocumentInteractionController的小伙伴都知道彰触,雖然它叫控制器梯投,但是它不是真正意義上的控制器而是繼承自NSObject的。這也就是為什么要遵循代理方法况毅,告訴UIDocumentInteractionController如何去顯示分蓖,比如顯示在當(dāng)前控制器,顯示的Rect等尔许。
下面是實(shí)現(xiàn)代碼:

#import "ViewController.h"

@interface ViewController ()<UIDocumentInteractionControllerDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title=@"預(yù)覽";
    
    NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"iOS開(kāi)發(fā)指南.pdf" ofType:nil];
    NSURL *url = [NSURL fileURLWithPath:urlStr];
    
    UIDocumentInteractionController *documentVc = [UIDocumentInteractionController interactionControllerWithURL:url];
    documentVc.delegate = self;
    
    [documentVc presentPreviewAnimated:YES];
    
}

#pragma mark - UIDocumentInteractionController 代理方法
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller{
    return self;
}

- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller{
    return self.view;
}

- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController *)controller{
    return self.view.bounds;
}

顯示的樣子是這樣的:

UIDocumentInteractionController-1.png

如果下面的代理方法不實(shí)現(xiàn)的話

- (UIView *)documentInteractionControllerViewForPreview:(UIDocumentInteractionController *)controller{
    return self.view;
}

是這樣子的:

UIDocumentInteractionController-2.png

在圖2的狀態(tài)單擊也會(huì)出現(xiàn)圖1的效果么鹤,隱藏導(dǎo)航欄。但是有個(gè)問(wèn)題是味廊,無(wú)法自定義這個(gè)導(dǎo)航欄蒸甜,可能說(shuō)無(wú)法自定義這有點(diǎn)絕對(duì),只是我現(xiàn)在還沒(méi)有找到好的辦法余佛,如果有哪位知道的話柠新,煩請(qǐng)指教,謝謝辉巡!
三恨憎、QLPreviewController
QLPreviewController的實(shí)現(xiàn)和UIDocumentInteractionController類(lèi)似,但是QLPreviewController是真正的控制器。兩者之間雖然實(shí)現(xiàn)效果相同憔恳,但是還是存在區(qū)別的瓤荔。
比如:QLPreviewController可以一起瀏覽多個(gè)文件,而UIDocumentInteractionController一次只能瀏覽一個(gè)文件钥组。
使用QLPreviewController之前输硝,需要導(dǎo)入QuickLook.framework,并遵守其數(shù)據(jù)源和代理方法程梦。實(shí)現(xiàn)代碼如下:

#import "ViewController.h"
#import <QuickLook/QuickLook.h>

@interface ViewController ()<QLPreviewControllerDataSource,QLPreviewControllerDelegate>

@end
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //控制當(dāng)前控制器對(duì)應(yīng)的導(dǎo)航條顯示的內(nèi)容
    self.navigationItem.title=@"預(yù)覽";
    
    NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"iOS開(kāi)發(fā)指南.pdf" ofType:nil];
    NSURL *url = [NSURL fileURLWithPath:urlStr];
    self.fileUrl = url;
    
    if ([QLPreviewController canPreviewItem:(id<QLPreviewItem>)url]) {
        QLPreviewController *qlVc = [[QLPreviewController alloc] init];
        qlVc.view.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64);
        qlVc.delegate = self;
        qlVc.dataSource = self;
        qlVc.navigationController.navigationBar.userInteractionEnabled = YES;
        qlVc.view.userInteractionEnabled = YES;
        [self presentViewController:qlVc animated:YES completion:nil];
    }
}

#pragma mark - QLPreviewController 代理方法
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller{
    return 1;
}

- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index{
    return self.fileUrl;
}

@end

實(shí)現(xiàn)的效果如圖2是一樣的点把,但是使用QLPreviewController能夠?qū)崿F(xiàn)替換導(dǎo)航欄的問(wèn)題,比如我們的需求為不需要右上角調(diào)出Menu項(xiàng)供選擇作烟,但是需要標(biāo)題和返回按鈕愉粤,在下面的代碼中這樣修改:

if ([QLPreviewController canPreviewItem:(id<QLPreviewItem>)url]) {
        QLPreviewController *qlVc = [[QLPreviewController alloc] init];
        qlVc.view.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64);
        qlVc.delegate = self;
        qlVc.dataSource = self;
        qlVc.navigationController.navigationBar.userInteractionEnabled = YES;
        qlVc.view.userInteractionEnabled = YES;
        [self.view addSubview:qlVc.view];
        [self presentViewController:qlVc animated:YES completion:nil];
    }

將QLPreviewController的view添加到當(dāng)前控制器的view上,如下:

[self.view addSubview:qlVc.view];
QLPreviewController-3.png

但是這樣的話又出現(xiàn)了新的問(wèn)題拿撩,其本身的導(dǎo)航欄不見(jiàn)了衣厘,顯示在你眼前的是你自己導(dǎo)航欄,如果需求改為需要右上角功能压恒,這時(shí)就尷尬了影暴,所以這其中的取舍需要具體的業(yè)務(wù)來(lái)決定了。
接下來(lái)看下QLPreviewControllerDataSource方法:

- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller{
    return 1;
}

這里我返回的PreviewItems的數(shù)量為1探赫,就是一次加載一個(gè)文件型宙,這里可以是多個(gè)文件的數(shù)組個(gè)數(shù),也就是某個(gè)本地路徑下的多個(gè)文件伦吠,大家可以自己實(shí)現(xiàn)下妆兑。

- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index{
    return self.fileUrl;
}

返回的當(dāng)前預(yù)覽的文件QLPreviewItem,controller:當(dāng)前預(yù)覽控制器,index:當(dāng)前預(yù)覽的第幾個(gè)文件毛仪。 這里為什么返回Url呢搁嗓,進(jìn)入QLPreviewItem頭文件你就會(huì)明白了:

QL_EXPORT @protocol QLPreviewItem <NSObject>

@required

/*!
 * @abstract The URL of the item to preview.
 * @discussion The URL must be a file URL. 
 */
@property(readonly, nonnull, nonatomic) NSURL * previewItemURL;

@optional

/*!
 * @abstract The item's title this will be used as apparent item title.
 * @discussion The title replaces the default item display name. This property is optional.
 */
@property(readonly, nullable, nonatomic) NSString * previewItemTitle;


@end

/*!
 * @abstract This category makes NSURL instances as suitable items for the Preview Controller.
 */
@interface NSURL (QLPreviewConvenienceAdditions) <QLPreviewItem>

其實(shí)NSURL的分類(lèi)遵循了QLPreviewItem協(xié)議,所以是可以返回Url的箱靴,這里可以返回一個(gè)Url數(shù)組腺逛。這就是預(yù)覽多個(gè)文件時(shí)的數(shù)據(jù)源方法,注意:以上兩個(gè)方法是@required的衡怀,必須需要實(shí)現(xiàn)的棍矛。
QLPreviewController還有一些代理方法,供你選擇性實(shí)現(xiàn)抛杨,比如說(shuō):

- (void)previewControllerWillDismiss:(QLPreviewController *)controller;

QLPreviewController將要消失的時(shí)候你可以處理一些邏輯够委,還有一些就不列舉了,大家可以進(jìn)入頭文件了解一下怖现。
自定義預(yù)覽控制器慨绳,一直沒(méi)有好的辦法,如有知道的童鞋,煩請(qǐng)指教下脐雪,順便說(shuō)下,剛剛接觸這塊恢共,如有錯(cuò)誤战秋,也請(qǐng)指出,多謝讨韭!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末脂信,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子透硝,更是在濱河造成了極大的恐慌狰闪,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件濒生,死亡現(xiàn)場(chǎng)離奇詭異埋泵,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)罪治,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)丽声,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人觉义,你說(shuō)我怎么就攤上這事雁社。” “怎么了晒骇?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵霉撵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我洪囤,道長(zhǎng)徒坡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任箍鼓,我火速辦了婚禮崭参,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘款咖。我一直安慰自己何暮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布铐殃。 她就那樣靜靜地躺著海洼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪富腊。 梳的紋絲不亂的頭發(fā)上坏逢,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼是整。 笑死肖揣,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浮入。 我是一名探鬼主播龙优,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼事秀!你這毒婦竟也來(lái)了彤断?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤易迹,失蹤者是張志新(化名)和其女友劉穎宰衙,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體睹欲,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡供炼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了句伶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劲蜻。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖考余,靈堂內(nèi)的尸體忽然破棺而出先嬉,到底是詐尸還是另有隱情,我是刑警寧澤楚堤,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布疫蔓,位于F島的核電站,受9級(jí)特大地震影響身冬,放射性物質(zhì)發(fā)生泄漏衅胀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一酥筝、第九天 我趴在偏房一處隱蔽的房頂上張望滚躯。 院中可真熱鬧,春花似錦嘿歌、人聲如沸掸掏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丧凤。三九已至,卻和暖如春步脓,著一層夾襖步出監(jiān)牢的瞬間愿待,已是汗流浹背浩螺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仍侥,地道東北人要出。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像农渊,于是被迫代替她去往敵國(guó)和親厨幻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,182評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)腿时、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,107評(píng)論 4 62
  • 2016年新番饭宾,打開(kāi)一看批糟,畫(huà)風(fēng)不是我喜歡的類(lèi)型,但是既然是朋友推薦看的看铆,那就試著看下去吧徽鼎,反正只有九集,可是看了...
    喜歡漫畫(huà)的咖啡店閱讀 576評(píng)論 0 1
  • 一弹惦、2017年簡(jiǎn)書(shū)輸出目標(biāo) 簡(jiǎn)書(shū)輸出20萬(wàn)字否淤,獲得喜歡60個(gè)。 二棠隐、2017年簡(jiǎn)書(shū)輸出統(tǒng)計(jì) 17年4月份 4月01...
    易查理閱讀 110評(píng)論 0 0
  • 選擇為你加班熬夜的石抡,還是地啊你花前月下的,從來(lái)都是個(gè)心結(jié)助泽。王偉在為了拉拉跟別人動(dòng)手啰扛,鏡頭切換,拉拉在心不在焉地看陳...
    怡怡怡寶兒閱讀 354評(píng)論 0 0