iOS--PDF

前言web

前面一段時間,一直在學習一些經常使用技術的底層的原理,由於我以爲只是會用不會很好的理解也不能很好的在開發的過程當中定位出現的bug,因此花了點時間去學習category、block以及runloop(AFNetworking中的常駐線程)的一些知識,去查閱資料而後理解它們的特性(好比category只能增長方法不能增長實例變量等等),主要是想在使用的過程當中能更好的選擇實現方式去解決問題,因此近段時間一直沒有寫博客;今天週末,新的app版本也已提交appstore,項目中有一些須要改進的地方,先提早進行相關知識點的學習,以備不時之需,好了廢話很少說,開始咱們今天的內容--在IOS中預覽pdf文件,顯示pdf文件通常使用兩種方式,一種是UIWebView,這種方式怎麼說呢優勢就是除了簡單仍是簡單,直接顯示pdf文件;另外的一種是自定義UIView,配合CGPDFDocumentRef讀取pdf文件裏面的內容,在自定義的drawRect方法中描繪獲取的pdf內容;其實還有一種的方式,就是蘋果在IOS4.0後,apple推出新的文件預覽控件:QLPreveiewController,支持pdf文件閱讀。今天我主要寫的是自定義View+CGPDFDocumentRef顯示pdf文件;網絡

 

(一)先運用CGPDFDocumentRef獲取指定的pdf內容;下面是我寫出的獲取內容的方法;app

//用於本地pdf文件
- (CGPDFDocumentRef)pdfRefByFilePath:(NSString *)aFilePath
{
    CFStringRef path;
    CFURLRef url;
    CGPDFDocumentRef document;
    
    path = CFStringCreateWithCString(NULL, [aFilePath UTF8String], kCFStringEncodingUTF8);
    url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, NO);
    document = CGPDFDocumentCreateWithURL(url);
    
    CFRelease(path);
    CFRelease(url);
    
    return document;
}

- (NSString *)getPdfPathByFile:(NSString *)fileName
{
    return [[NSBundle mainBundle] pathForResource:fileName ofType:@".pdf"];
}

//用於網絡pdf文件
- (CGPDFDocumentRef)pdfRefByDataByUrl:(NSString *)aFileUrl
{
    NSData *pdfData = [NSData dataWithContentsOfFile:aFileUrl];
    CFDataRef dataRef = (__bridge_retained CFDataRef)(pdfData);
    
    CGDataProviderRef proRef = CGDataProviderCreateWithCFData(dataRef);
    CGPDFDocumentRef pdfRef = CGPDFDocumentCreateWithProvider(proRef);
    
    CGDataProviderRelease(proRef);
    CFRelease(dataRef);
    
    return pdfRef;
}

經過文件路徑解析pdf文件,返回文件內容。ide

 

(二)第二步就是在自定義的View中繪製pdf內容;oop

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGPDFPageRef pageRef = CGPDFDocumentGetPage(pdfRef, catPage);//獲取指定頁的內容如catPage=1,獲取的是pdf第一頁的內容
    CGRect mediaRect = CGPDFPageGetBoxRect(pageRef, kCGPDFCropBox);//pdf內容的rect
    
    CGContextRetain(context);
    CGContextSaveGState(context);
    
    [[UIColor whiteColor] set];
    CGContextFillRect(context, rect);//填充背景色,不然爲全黑色;
    
    CGContextTranslateCTM(context, 0, rect.size.height);//設置位移,x,y;
    
    CGFloat under_bar_height = _hasNavBar ? -64.0f : 0.0f;
    CGContextScaleCTM(context, rect.size.width / mediaRect.size.width, -(rect.size.height + under_bar_height) / mediaRect.size.height);//縮放倍數--x軸和y軸
    
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    CGContextSetRenderingIntent(context, kCGRenderingIntentDefault);
    CGContextDrawPDFPage(context, pageRef);//繪製pdf
    
    CGContextRestoreGState(context);
    CGContextRelease(context);
}

以上就是繪製pdf的內容的代碼,代碼每行我都寫了註釋,其實都是很好了解的。學習

固然上面的只是顯示pdf指定頁的邏輯,要想顯示整個pdf文件的內容,須要配合UIScrollView或者是UIPageViewController去實現,原理也很簡單,結合上述的邏輯只要傳入一個pageIndex的值,刷新頁面內容就能夠實現。下面是我寫的一個列子,pageviewcontroller實現;ui

self.pdfArr = [NSMutableArray array];
    NSDictionary *options =[NSDictionary dictionaryWithObject:[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMin]
                                                       forKey: UIPageViewControllerOptionSpineLocationKey];
    
    self.pageVC = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];
    
    _pageVC.view.frame = self.view.bounds;
    _pageVC.delegate = self;
    _pageVC.dataSource = self;
    [self addChildViewController:_pageVC];
    
    PDFView *testPdf = [[PDFView alloc] init];
    NSString *pathStr = [[NSBundle mainBundle] pathForResource:@"test-pdf" ofType:@".pdf"];
    CGPDFDocumentRef pdfRef = [testPdf createPDFFromExistFile:pathStr];
    size_t count = CGPDFDocumentGetNumberOfPages(pdfRef);//這個位置主要是獲取pdf頁碼數;

    for (int i = 5; i < count; i++) {
        PDFContentVC *pdfVC = [[PDFContentVC alloc] init];
        PDFView *pdfView = [[PDFView alloc] initWithFrame:self.view.frame atPage:(i+1) andFileName:@"test-pdf"];
        pdfVC.pdfView = pdfView;
        [pdfVC.view addSubview:pdfVC.pdfView];
        
        [_pdfArr addObject:pdfVC];
    }
    
    
    [_pageVC setViewControllers:[NSArray arrayWithObject:_pdfArr[0]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
    [self.view addSubview:_pageVC.view];


//委託方法;
- (PDFContentVC *)viewControllerAtIndex:(NSInteger)index
{
    //Create a new view controller and pass suitable data.
    
    if (([_pdfArr count] == 0 )|| (index > [_pdfArr count]) ) {
        return nil;
    }

    
    NSLog(@"index = %ld",(long)index);
    
    return (PDFContentVC *)_pdfArr[index];
}


- (NSUInteger) indexOfViewController:(PDFContentVC *)viewController
{
    return [self.pdfArr indexOfObject:viewController];
}


- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(PDFContentVC *)viewController];
    if (index == NSNotFound) {
        return nil;
    }
    
    index++;
    
    if (index == [_pdfArr count]){
        return  nil;
    }
    
    return [self viewControllerAtIndex:index];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [self indexOfViewController:(PDFContentVC *)viewController];
    if ((index == 0 ) || (index == NSNotFound)){
        return nil;
    }
    
    index--;
    
    return [self viewControllerAtIndex:index];
}

以上就是簡單的實現;url

 

(三)對於第三種方法,使用QLPreveiewController去預覽pdf,我就沒有具體的經過代碼去實現pdf的預覽,在網絡上應該有資源可查;線程

QLPreveiewController的用法;已經簡單的說了一下怎麼去預覽pdf內容,也是很簡單的,若是想要自定義顯示的話,須要本身花時間去研究了。code

 

總結

無論是選用哪種方式,均可以實現加載pdf文件;webview除了簡單粗暴可是隻能做爲簡單的瀏覽,CGPDFDocumentRef須要開發者本身去實現顯示的邏輯,但這樣可控性會比較好,顯示的效果也是能夠自定義,QLPreveiewController的話,我沒有本身去實現過,因此你們能夠去試試。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息