【问题标题】:Get PDF document height in iOS WebView在 iOS WebView 中获取 PDF 文档高度
【发布时间】:2015-11-15 08:19:32
【问题描述】:

我尝试通过NSURLUIWebView 中显示PDF。它工作正常。

但是我不知道pdf文档的高度。所以有时它会创建空白空间或需要滚动。 PDF 也可能包含多个页面。

如果它包含多页,我只想显示第一页。

我的代码如下:

NSURL *url = [NSURL URLWithString:@"http://www.eecs.harvard.edu/econcs/pubs/online.pdf"];
 NSURLRequest * request = [NSURLRequest requestWithURL:url];
    [web_large loadRequest:request];
    [web_large setScalesPageToFit:YES];

现在,WebView 的高度是固定的

【问题讨论】:

  • 如果您只需要文档的高度,那么这个问题就是重复的。如果您需要给定页面中占用的空间量,您可能需要重新考虑您的方法,因为 PDF 本质上是一种可移植文档格式,超越了平台和浏览器。如果该空白是文档的创建者想要的,这可能是在 PDF 文档创建为页面时,您可以考虑显示它。

标签: ios objective-c iphone pdf uiwebview


【解决方案1】:

Pradumna Patil 的回答是正确的。我将您的代码与他的代码结合在一起,效果很好。只需将以下行粘贴到您的项目中,然后自己查看:

UIWebView *web_large = [[UIWebView alloc]init];
[self.view addSubview:web_large];

NSURL *url = [NSURL URLWithString:@"https://www.truthinadvertising.org/wp-content/uploads/2014/09/App-Store-Review-Guidelines.pdf"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
[web_large loadRequest:request];
[web_large setScalesPageToFit:YES];

CGPDFDocumentRef pdfDocumentRef = CGPDFDocumentCreateWithURL((CFURLRef)url);
CGPDFPageRef pdfPageRef = CGPDFDocumentGetPage(pdfDocumentRef, 1);

CGRect pdfPageRect = CGPDFPageGetBoxRect(pdfPageRef, kCGPDFMediaBox);

float width = pdfPageRect.size.width;
float height = pdfPageRect.size.height;

CGRect screenRect = [[UIScreen mainScreen]bounds];
web_large.frame = CGRectMake(0, 0, screenRect.size.width, height*screenRect.size.width/width);

【讨论】:

  • 对我不起作用。 CGPDFDocumentCreateWithURL 是异步的吗?
  • @turingtested 在加载“https” url 时对我不起作用。请尽快提供帮助
  • @YogendraPatel,此代码仍在为我工作(但 UIWebView 现在已弃用)。我刚刚使用带有 https 的更新 URL 测试了代码(见上文)。所以这不是代码,也许你通过 Info.plist 中的 App Transport Security 设置对应用程序进行了限制?
  • @turingtested 你能建议 info.plist 的代码吗?
  • @turingtested 你在哪个版本中测试过?因为这个问题只发生在ios12以下。它在 ios12 中完美运行。
【解决方案2】:

在 Swift 中你可以这样做:

let documents = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let writePath = documents?.appending("/myPdf.pdf")
let pdf: CGPDFDocument! = CGPDFDocument(URL.init(fileURLWithPath: writePath!) as CFURL)`enter code here`
let firstPage: CGPDFPage = pdf.page(at: 1)!
let heightFirstPage :CGRect =  firstPage.getBoxRect(.mediaBox) 
var heightPagePdf : CGFloat = heightFirstPage.height;

变量'pdf'还有一个属性'numberOfPages',所以你可以知道pdf文档的整个高度(pdf.numberOfPages * heightPagePdf)。

最好的尊重

【讨论】:

    【解决方案3】:

    试试这个

    有这个方法:

    size_t CGPDFDocumentGetNumberOfPages(CGPDFDocumentRef document)
    

    这会给你number of pages

    例如。

    NSURL *pdfUrl = [NSURL fileURLWithPath:yourPath];    
    CGPDFDocumentRef document = CGPDFDocumentCreateWithURL((CFURLRef)pdfUrl);
    

    以下代码在pdf 文件中给出heightsingle page

      float width = CGPDFPageGetBoxRect(pdfPageRef, kCGPDFMediaBox).size.width;
        float height = CGPDFPageGetBoxRect(pdfPageRef, kCGPDFMediaBox).size.height;
    

    希望对你有帮助。

    【讨论】:

    • 感谢您的回答!但它给出了错误的高度!例如它的高度为 800,但如果我为网页视图设置 800 像素高度,那么它似乎有很多空白空间!
    • @user2526811 来自 CGPDFPageGetBoxRect 的尺寸是文档的原生尺寸,您需要将 web 视图的高度设置为“web_large.frame.size.width * (height / width)”,所以高度是文档大小的比率
    【解决方案4】:

    这个很简单。

    您必须访问 webView 的滚动视图而不是 webview 本身:

    CGFloat totalHeight = self.webView.scrollView.contentSize.height;
    

    【讨论】:

    • ^为什么这不被接受为答案,这完全正确地给出了 webview 中 pdf 内容的所需高度
    • 该人专门说“但是我不知道pdf文档的高度”,问题的标题是:“在iOS WebView中获取PDF文档高度”我认为我的回答非常适合那些情况@SwiftArchitect 我认为其他回答它的人都把它带到了不同的方向
    • 对。我可以发誓它不是那样开始的。那么这不是stackoverflow.com/questions/20755231/…stackoverflow.com/questions/3045587/…的重复吗?
    • @SwiftArchitect 我同意这是重复的。但我只是为了获得一些代表的廉价机会而加入潮流;)只是诚实
    • @SahebRoy 评估它不是你的工作。但是,如果您觉得答案有用,您应该投票赞成。
    【解决方案5】:

    我建议您不要在 webView 中加载 pdf,而是在 UIView 中绘制 PDF,就像我在自己的项目中所做的那样,它运行良好。 下面是我的 UIView 子类,它在 UIView 上下文中绘制 pdf。

    PDFPage.h

    #import <UIKit/UIKit.h>
    
    @protocol PDFPageDelegate;
    
    
    
    @interface PDFPage : UIView
    
    @property    uint                   currentPage;
    @property    unsigned long          totalPages;
    @property    CGRect                 pageRect;
    @property    NSString               *pdfPath;
    @property    id<PDFPageDelegate>    delegate;
    
    
    - (CGRect)setPdf:(NSString*)filePath;
    - (void)swipeLeft;
    - (void)swipeRight;
    - (void)setPageNumber:(NSUInteger )targetPageNumber;
    
    @end
    
    
    
    
    
    
    
    @protocol PDFPageDelegate <NSObject>
    
    - (void)pdfWillSwipeToLeft:(uint)upcommingPageNumber;
    - (void)pdfWillSwipeToRight:(uint)upcommingPageNumber;
    - (void)pdfTaped:(CGPoint)tapAt;
    - (void)pdfDoubleTapped;
    
    @end
    

    PDFPage.m

    #import "PDFPage.h"
    
    @implementation PDFPage
    
    @synthesize pageRect        = _pageRect;
    @synthesize currentPage     = _currentPage;
    @synthesize totalPages      = _totalPages;
    @synthesize delegate        = _delegate;
    @synthesize pdfPath         = _pdfPath;
    
    
    
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {}
    
        _currentPage = 1;
    
        UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft)];
        swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
        [self addGestureRecognizer:swipeLeft];
    
    
        UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight)];
        swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
        [self addGestureRecognizer:swipeRight];
    
        return self;
    }
    
    
    
    - (void)setPageNumber:(NSUInteger )targetPageNumber
    {
        _currentPage = (uint)targetPageNumber;
    
        [self setNeedsDisplay];
        [UIView transitionWithView:self duration:0.5
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        [self.layer displayIfNeeded];
                    } completion:nil];
    }
    
    - (void)swipeLeft
    {
        if(_currentPage == _totalPages)
            return;
    
        _currentPage++;
    
        [_delegate pdfWillSwipeToLeft:_currentPage];
    
        [self setNeedsDisplay];
        [UIView transitionWithView:self duration:0.5
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        [self.layer displayIfNeeded];
                    } completion:nil];
    }
    
    - (void)swipeRight
    {
        if(_currentPage == 1)
            return;
    
    
        _currentPage--;
    
    
        [_delegate pdfWillSwipeToRight:_currentPage];
    
    
        [self setNeedsDisplay];
        [UIView transitionWithView:self duration:0.5
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        [self.layer displayIfNeeded];
                    } completion:nil];
    
    }
    
    
    
    - (void)drawRect:(CGRect)rect
    {
        CGContextRef ctx = UIGraphicsGetCurrentContext();
    
        // PDF might be transparent, assume white paper
        [[UIColor whiteColor] set];
        CGContextFillRect(ctx, rect);
    
        // Flip coordinates
        CGContextGetCTM(ctx);
        CGContextScaleCTM(ctx, 1, -1);
        CGContextTranslateCTM(ctx, 0, -rect.size.height);
    
        // url is a file URL
        CFURLRef pdfURL = (__bridge CFURLRef)[NSURL fileURLWithPath:_pdfPath];
        CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL(pdfURL);
        CGPDFPageRef page1 = CGPDFDocumentGetPage(pdf, _currentPage);
    
        // get the rectangle of the cropped inside
        CGRect mediaRect = CGPDFPageGetBoxRect(page1, kCGPDFCropBox);
    
        CGContextScaleCTM(ctx, rect.size.width / mediaRect.size.width,
                      rect.size.height / mediaRect.size.height);
        CGContextTranslateCTM(ctx, -mediaRect.origin.x, -mediaRect.origin.y);
    
        // draw it
        CGContextDrawPDFPage(ctx, page1);
        CGPDFDocumentRelease(pdf);
    }
    
    
    
    - (CGRect)setPdf:(NSString*)filePath
    {
    
        _pdfPath =filePath;
        _currentPage = 1;
        CFURLRef pdfURL = (__bridge CFURLRef)[NSURL fileURLWithPath:_pdfPath];
    
        CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL(pdfURL);
        CGPDFPageRef page = CGPDFDocumentGetPage(pdf,_currentPage);
    
        _pageRect = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
        _totalPages = (CGPDFDocumentGetNumberOfPages(pdf));
        [self setNeedsDisplay];
        [UIView transitionWithView:self duration:0.5
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        [self setNeedsDisplay];
                    } completion:nil];
    
        CGRect finalRect = CGRectMake(0, 0, _pageRect.size.width, _pageRect.size.height);
    
        return finalRect;
    }
    

    如何使用:-

        NSData *pdfData = [NSData dataWithContentsOfURL:[NSURL URLWithString:pdfPath]]; // here pdfPath is webURL
    
        NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString * savePDFAt = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
        savePDFAt = [NSString stringWithFormat:@"%@/PDFs/",savePDFAt];
        [[NSFileManager defaultManager] createDirectoryAtPath:savePDFAt withIntermediateDirectories:NO attributes:nil error:nil];
        [savePDFAt stringByAppendingPathComponent:"test.pdf"];
    
        if([pdfData writeToFile:savePDFAt options:0 error:&error])
            NSLog(@"PDF download complete");
    
        PDFPage *pdfPage = [PDFPage new];
        pdfPage.alpha = 0.0f;
        pdfPage.delegate = self;
        pdfPage.frame = [pdfPage setPdf:pdfPath];
    

    然后将此 pdfPage 添加到自己的视图或滚动条中。

    【讨论】:

    • 在如何使用示例中没有声明''pdfPath''变量
    【解决方案6】:

    试试这个..它工作正常

     NSURL* pdfFileUrl = targetURL;
    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfFileUrl);
    
    CGFloat pdfHeight = 0;
    NSUInteger totalNum = CGPDFDocumentGetNumberOfPages(pdf);
     for(int i = 0; i < totalNum; i++ ) {
        CGPDFPageRef myPageRef=CGPDFDocumentGetPage(pdf, i+1);
        CGRect cropBox = CGPDFPageGetBoxRect(myPageRef, kCGPDFCropBox);
        pdfHeight+=cropBox.size.height;
        int pageRotation = CGPDFPageGetRotationAngle(myPageRef);
        CGSize pageVisibleSize = CGSizeMake(cropBox.size.width, cropBox.size.height);
        if ((pageRotation == 90) || (pageRotation == 270) ||(pageRotation == -90)) {
            pageVisibleSize = CGSizeMake(cropBox.size.height, cropBox.size.width);
        }
    }
    NSLog(@"%f",pdfHeight);
    

    【讨论】:

    • 感谢您的回答!等等..我正在检查
    • 对不起!但它不工作!如果我认为 pdf 只有 1 页,答案是一样的。它给出的高度为 800,但它显示了很多空白空间!
    猜你喜欢
    • 2013-03-22
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 2012-03-26
    相关资源
    最近更新 更多