iOS加載PDF文件

本文主要介紹一下iOS加載PDF的方法。git

使用webView加載

使用webView加載是最簡單的方式,這是最大的優勢,使用方便,而且能夠加在網絡文件,缺點就是效果體驗不怎麼好,單一的上下滑動效果。github

注意:web

UIWebview組件已經在今年被apple禁用,使用webView沒法提交App Store,本文下面使用的都是基於WKWebViewobjective-c

首先看一下 webView加載的方法,markdown

- (nullable WKNavigation *)loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL

921EC7F6-6D72-4D7E-88CA-120F18C50BBF

該方法第一個參數URL自不用說,是咱們想要加載的文件的路徑,注意看apple的解釋,這是一個file URL,咱們應該使用下面這個方法的結果做爲參數。網絡

NSURL *fileUrl = [NSURL fileURLWithPath:@"path"];
複製代碼

第二個參數readAccessURL,是用來傳入頁面引用資源的路徑,正常是前面File URL的上級目錄,備註也寫的很詳細,若是該參數傳入的是單一的文件,那麼只有這個文件能被WebKit加載。app

若是出現了PDF亂碼的狀況,使用下面這個方法進行加載:框架

[self.wkWebView loadData:data MIMEType:@"application/pdf" characterEncodingName:@"GBK" baseURL:fileUrl];	
複製代碼

使用QLPreviewController

使用QLPreviewController須要導入QuickLook框架oop

#import <QuickLook/QuickLook.h>		
複製代碼

遵循QLPreviewControllerDelegate和QLPreviewControllerDataSource,動畫

使用方式以下:

@property (nonatomic, strong) QLPreviewController *previewController;
複製代碼
- (QLPreviewController *)previewController {
    if (!_previewController) {
        _previewController = [[QLPreviewController alloc] init];
        _previewController.delegate = self;
        _previewController.dataSource = self;
    }
    return _previewController;
}	
複製代碼

實現協議:

/// 返回文件數量
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller {
    return 1;
}

- (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index {
    NSString *pdfPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"pdf"];
    return [NSURL fileURLWithPath:pdfPath];
}	
複製代碼

還有一種方式是使用UIDocumentInteractionController進行預覽,效果與QLPreviewController同樣,可是不支持多文件預覽。

使用時也須要遵循UIDocumentInteractionControllerDelegate。

- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller {
    return self;
}
- (UIView*)documentInteractionControllerViewForPreview:(UIDocumentInteractionController*)controller {
    return self.view;
}
- (CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController*)controller {
    return self.view.frame;
}
複製代碼

UIDocumentInteractionController繼承於NSObject,而非UIViewController,使用該類自帶的presentPreviewAnimated方法展現。

這兩種的加載方法優點是,

  1. 集成方便,而且自帶系統分享功能

  2. QLPreviewController支持多文件預覽

劣勢的話就是體驗比較差,與webView相似的上下滑動的預覽方式

CGContexDrawPDFPage

若是咱們須要一個比較好的體驗效果,相似於翻書同樣的動畫效果,這個時候咱們就須要使用CGContexDrawPDFPage來進行本身繪製。

  1. 獲取PDF文件

    /// 獲取路徑
        CFStringRef path = CFStringCreateWithCString(NULL, filePath.UTF8String, kCFStringEncodingUTF8);
        CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, NO);
        /// 獲取PDF
        CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url);
        /// 主動釋放
        CFRelease(path);
        CFRelease(url);	
    複製代碼
  2. 獲取PDF頁數

    NSInteger totoalPages = CGPDFDocumentGetNumberOfPages(document);
    複製代碼
  3. 獲取頁數內容

    CGPDFPageRef page = CGPDFDocumentGetPage(document, _currentPage);
    複製代碼
  4. 獲取當前頁的大小

    CGRect rect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
    複製代碼
  5. 繪製當前頁內容

    - (void)drawRect:(CGRect)rect {
        
        CGContextRef context = UIGraphicsGetCurrentContext();
        [[UIColor whiteColor] set];
        CGContextFillRect(context, rect);
        
        /// 轉換座標系
        CGContextTranslateCTM(context, 0.0, rect.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        
        CGPDFPageRef page = CGPDFDocumentGetPage(document, _currentPage);
        CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(page, kCGPDFCropBox, rect, 0, true);
        CGContextConcatCTM(context, pdfTransform);
        CGContextDrawPDFPage(context, page);
    }
    複製代碼
  6. 最後一步加上翻頁動畫

    /// 返回上一頁
        [self transitionWithType:@"pageUnCurl" subtype:kCATransitionFromRight];
    /// 下一頁
        [self transitionWithType:@"pageCurl" subtype:kCATransitionFromRight];
    
    複製代碼
    - (void)transitionWithType:(NSString *)type subtype:(CATransitionSubtype)subType {
    
        CATransition *animation = [CATransition animation];
        /// 設置動畫時長
        animation.duration = 0.8;
        /// 設置動畫樣式
        /***
         使用CATransitionType
         kCATransitionPush 推入效果
         kCATransitionMoveIn 移入效果
         kCATransitionReveal 截開效果
         kCATransitionFade 漸入漸出效果
         或者直接使用如下字符串:
         cube 方塊
         suckEffect 三角
         rippleEffect 水波抖動
         pageCurl 上翻頁
         pageUnCurl 下翻頁
         oglFlip 上下翻轉
         cameraIrisHollowOpen 鏡頭快門開
         cameraIrisHollowClose 鏡頭快門開
        */
        animation.type = type;
        
        /// 設置動畫方向
        /**
         kCATransitionFromRight     從右邊
         kCATransitionFromLeft      從左邊
         kCATransitionFromTop       從上面
         kCATransitionFromBottom    從下面
         */
        if (subType) {
            animation.subtype = subType;
        }
        /// 動畫的速度
        /** CAMediaTimingFunction:
            kCAMediaTimingFunctionLinear 勻速
            kCAMediaTimingFunctionEaseIn 慢進快出
            kCAMediaTimingFunctionEaseOut 快進慢出
            kCAMediaTimingFunctionEaseInEaseOut 慢進慢出 中間加速
            kCAMediaTimingFunctionDefault 默認
         */
        animation.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseIn];
        [self.layer addAnimation:animation forKey:@"animation"];
    }
    複製代碼

    附上簡單的Demo

相關文章
相關標籤/搜索