有没有办法以编程方式滚动到UIWebView中的PDF页面?

时间:2009-12-18 12:06:33

标签: iphone pdf uiwebview cgpdfdocument

可以使用JavaScript设置UIWebView的像素y偏移量,例如:

[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"scrollTo(0, %d)", offset]];

有没有办法获得:

  1. 网页视图中PDF的单个页面的像素高度?
  2. 页面之间的差距大小?
  3. 这些信息是否可以从UIWebView获得,还是可以通过其他方式计算出来?

    我想如果我有页数(通过CGPDFDocumentGetNumberOfPages),页面之间的像素高度差距,或单个页面的像素高度,我可以计算offset到与JavaScript调用一起使用。然后,我只需连接UIButtonUISlider即可在页面之间移动。


    编辑我

    我有一个解决方案,但它使用UIWebDocumentViewUIWebView的私有子视图。

    我创建了一个名为PDFViewerViewController的视图控制器,它是WebViewerViewController的子类,它本身是一个视图控制器,包含UIToolbarUIWebView,并且符合到UIWebViewDelegate协议。

    我的PDFViewerViewController在调用Web视图委托方法-webViewDidFinishLoad:后,计算有关封闭Web视图和PDF数据的一些信息。

    此信息用于计算通过JavaScript提供给Web视图的大致每页偏移量。

    PDFViewerViewController.h

    #import <UIKit/UIKit.h>
    #import "WebViewerViewController.h"
    
    @interface UIWebDocumentView : NSObject {}
    @end
    
    @interface PDFViewerViewController : WebViewerViewController {
        NSUInteger offset;
        NSUInteger currentPage;
        NSUInteger documentPages;
        CGFloat documentHeight;
        CGFloat pageHeight;
    }
    
    @property (assign) NSUInteger offset;
    @property (assign) NSUInteger currentPage;
    @property (assign) NSUInteger documentPages;
    @property (assign) CGFloat documentHeight;
    @property (assign) CGFloat pageHeight;
    
    @end
    

    PDFViewerViewController.m

    #import "PDFViewerViewController.h"
    
    @implementation PDFViewerViewController
    
    @synthesize offset;
    @synthesize currentPage;
    @synthesize documentPages;
    @synthesize documentHeight;
    @synthesize pageHeight;
    
    - (void) viewDidLoad {
        [super viewDidLoad];
    
        UIBarButtonItem *_leftArrow = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ArrowLeft.png"] style:UIBarButtonItemStylePlain target:self action:@selector(leftArrow:)];
        UIBarButtonItem *_flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
        UIBarButtonItem *_rightArrow = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"ArrowRight.png"] style:UIBarButtonItemStylePlain target:self action:@selector(rightArrow:)];
        [[super.viewerToolbarView toolbar] setItems:[NSArray arrayWithObjects:_leftArrow, _flexibleSpace, _rightArrow, nil]];
        [_leftArrow release];
        [_flexibleSpace release];
        [_rightArrow release];
    
        self.currentPage = 0;
    }
    
    - (void) webViewDidFinishLoad:(UIWebView *)_webView {
        for (UIView *_subview in [[[_webView subviews] objectAtIndex:0] subviews]) {
            if ([_subview isKindOfClass:[UIWebDocumentView class]]) {
                self.documentHeight = _subview.bounds.size.height;
            }
        }
    
        CGPDFDocumentRef pdfDocument = CGPDFDocumentCreateWithURL((CFURLRef)baseURL);
        self.documentPages = CGPDFDocumentGetNumberOfPages(pdfDocument);
        CGPDFDocumentRelease(pdfDocument);
    
        self.pageHeight = (self.documentHeight + (10 * self.documentPages)) / self.documentPages;
        self.currentPage = 1;
        self.offset = 0;
    }
    
    - (void) leftArrow:(id)_param {
        if (self.currentPage == 1) 
            return;
        self.offset -= (NSUInteger)self.pageHeight;
        self.currentPage--;
        [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"scrollTo(0, %d)", (self.offset * 2)]];
    }
    
    - (void) rightArrow:(id)_param {
        if (self.currentPage == self.documentPages) 
            return;
        self.offset += (NSUInteger)self.pageHeight;
        self.currentPage++;
        [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"scrollTo(0, %d)", (self.offset * 2)]];
    }
    

    一些观察

    1. 偏移计算不是页面完美的。如果PDF文档不是8.5 x 11(例如A4),则偏移误差会更快地恶化。

    2. 通过触摸拖动滚动浏览Web视图时,self.currentPage属性不会更新。可能会拖动几页,然后触摸工具栏上的左箭头或右箭头会导致偏移意外移动到上一页。

    3. 此解决方案使用UIWebDocumentView,这是私有的,可能会导致应用拒绝。

    4. 我想我会向Apple提交功能增强请求。

      是否有人构建了基于非UIWebView的PDF查看器(带源代码)?

5 个答案:

答案 0 :(得分:4)

所以这篇文章已经开放了很长一段时间,但由于这是Google搜索“scroll pdf uiwebview”的第一篇文章,我想我会为未来的读者提供这些文章。

您确实可以使用纯Java脚本滚动到PDF文档中的特定页面。我已在我们的博客(http://apptech.next-munich.com/2011/02/pdf-in-uiwebview.html)上发布了示例代码,但这里是您需要做的简短摘要:

  1. 使用window.outerHeight DOM属性查找呈现的PDF文档的总高度。
  2. 使用window.innerHeight DOM属性在浏览器坐标中查找浏览器窗口的高度。
  3. 使用window.scrollTo(x,y)函数跳转到该页面。
  4. 但是,有一个问题是,您不能只按页数设置outerHeight并跳转到您获得的内容。相反,您必须乘以innerHeight / webView.bounds.size.height比率。

答案 1 :(得分:1)

我认为您必须使用PDF API而不是UIWebView自行加载和显示PDF。这里有一个可能的想法,即如何模拟捕捉滚动到矩形网格边界,这可以帮助您使用户体验更像UIWebView。

iPhone sdk Cocoa Touch - Pass touches down from parent UIView to child UIScrollview

答案 2 :(得分:1)

我看到你的编辑有问题了。 是否有人构建了基于非UIWebView的PDF查看器(带源代码)?

看我的问题。

Reading PDF files as string through iPhone application

它具有在图像视图中显示每个pdf页面的功能。用户可以轻松更改页面。但遗漏的要点如下。

  • 用户无法进行任何选择 - 因为它不是文本而是图像
  • 用户找不到任何文字。
  • 用户无法缩放(哦,是的 - 您可以将图像视图放在滚动视图中以进行缩放功能)

答案 3 :(得分:1)

通常用于加载pdf的uiwebview有自己的scrollview对象,你可以调用它。尝试这样的事情:

    [webview.scrollView setContentOffset:CGPointMake(0, webview.scrollView.contentOffset.y + 100) animated:YES];    

这会将pdf的视图向下滚动100像素。至于获取pdf的页面编号,我只能想象你需要看一下javascript。或者,如果您只知道pdf每页上的像素数,则根据需要增加或减少。 :)

答案 4 :(得分:1)

我遇到了类似的问题,我必须在tableView(缩略图tableview)中选择与该页面对应的单元格时滚动到PDF中的特定页面(使用UIWebView显示)。

所以我编写了一段代码,允许您滚动到PDF格式的特定页面。

我没有使用任何JavaScript代码。我只是跟踪每次应用于原始PDF页面的缩放比例,并计算滚动到每个页面所需的更新偏移量。因此,即使PDF处于缩放状态,这也能正常工作。

您可以找到代码here