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

时间:2022-08-24 23:26:33

It is possible to use JavaScript to set the pixel y-offset of a UIWebView, e.g.:

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

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

So is there a way to get:

有没有办法得到:

  1. The pixel height of an individual page of a PDF within the web view?
  2. Web视图中PDF的单个页面的像素高度?

  3. The size of the gap between pages?
  4. 页面之间的差距大小?

Is this information available from the UIWebView or can it be calculated through alternative means?

这些信息是否可以从UIWebView获得,还是可以通过其他方式计算出来?

I'm thinking that if I have the number of pages (via CGPDFDocumentGetNumberOfPages), the pixel height gap between pages, or the pixel height of an individual page, I can calculate the offset to use with the JavaScript call. Then I just wire up a UIButton or UISlider to move between pages.

我想如果我有页数(通过CGPDFDocumentGetNumberOfPages),页面之间的像素高度差距,或单个页面的像素高度,我可以计算用于JavaScript调用的偏移量。然后,我只需连接UIButton或UISlider即可在页面之间移动。


EDIT I

I have a solution, but it uses UIWebDocumentView, a private subview of UIWebView.

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

I create a view controller called PDFViewerViewController, which is a subclass of WebViewerViewController, which itself is a view controller that contains a UIToolbar, a UIWebView, and conforms to the UIWebViewDelegate protocol.

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

My PDFViewerViewController calculates some information about the enclosing web view and the PDF data, after the web view delegate method -webViewDidFinishLoad: gets called.

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

This information is used to calculate an approximate per-page offset that gets fed to the web view via JavaScript.

此信息用于计算通过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)]];
}

Some observations

  1. The offset calculation isn't page-perfect. If the PDF document isn't 8.5 x 11 (e.g. A4) then the offset error gets worse more quickly.

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

  2. The self.currentPage property doesn't get updated when scrolling through the web view by way of touch-drag. One might drag a few pages, and then touching the left or right arrow on the toolbar will cause the offset to unexpectedly move to a previous page.

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

  3. This solution uses UIWebDocumentView, which is private and may likely cause app rejection.

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

I think I'll file a feature enhancement request with Apple.

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

Has anyone built a non-UIWebView-based PDF viewer (with source code)?

有没有人构建一个非基于UIWebView的PDF查看器(带源代码)?

5 个解决方案

#1


4  

So this post has been open for quite a while now but since it's the first entry on a Google search for "scroll pdf uiwebview" I thought I'd provide my take at this for future readers.

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

You can indeed scroll to a particular page in a PDF document using nothing but pure Java Script. I've posted sample code on our blog (http://apptech.next-munich.com/2011/02/pdf-in-uiwebview.html) but here's a short summary of what you need to do:

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

  1. Use the window.outerHeight DOM property to find the total height of the rendered PDF document.
  2. 使用window.outerHeight DOM属性查找呈现的PDF文档的总高度。

  3. Use the window.innerHeight DOM property to find the height of the browser window in browser coordinates.
  4. 使用window.innerHeight DOM属性在浏览器坐标中查找浏览器窗口的高度。

  5. Jump to the page using the window.scrollTo(x, y) function.
  6. 使用window.scrollTo(x,y)函数跳转到该页面。

There is one catch, though, that you cannot just device the outerHeight by the number of pages and jump to what you get. Instead, you will have to multiply by the innerHeight/webView.bounds.size.height ratio.

但是,有一个问题是,您不能只按页数设置outerHeight并跳转到您获得的内容。相反,您必须乘以innerHeight / webView.bounds.size.height比率。

#2


1  

I think that you'll have to load and display the PDF yourself using the PDF APIs rather than UIWebView. Here is an possible idea of how to simulate snapping scrolling to rectangular grid boundaries which may help you make the experience more like a UIWebView for your users.

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

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

iPhone sdk Cocoa Touch - 从父母UIView传递给孩子UIScrollview

#3


1  

I have seen your edit in question. Has anyone built a non-UIWebView-based PDF viewer (with source code)?

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

See my question.

看我的问题。

Reading PDF files as string through iPhone application

通过iPhone应用程序将PDF文件读取为字符串

It has functionality to display each pdf page in an image view. user can easily change pages. But the missing points are as follows.

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

  • user can not make any selection - as it is not text but an image
  • 用户无法进行任何选择 - 因为它不是文本而是图像

  • user can't find any text.
  • 用户找不到任何文字。

  • user can not zoom ( oh yes - you can put image view in scroll view for zooming functionality )
  • 用户无法缩放(哦,是的 - 您可以将图像视图放在滚动视图中以进行缩放功能)

#4


1  

The uiwebview commonly used to load pdf's has it's own scrollview object that you can make calls to. try something like this:

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

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

This will scroll the view for the pdf down 100 pixels. As for getting the pagenumber of the pdf, I can only imagine that javascript is what you need to take a look at. Or, If you simply know the number of pixels on each page of the pdf, then increment or decrement as necessary. :)

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

#5


1  

I have faced a similar problem, in which I had to scroll to particular page in PDF (which is displayed using UIWebView) on selection of a cell corresponding to that page in tableView (thumbnail tableview).

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

So I wrote a piece of code which allows you to scroll to particular page in PDF.

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

I am not using any javascript code. I am just keeping track of the zoom scale applied to the original PDF page each time and calculating the updated offset required to scroll to each page. So, this works even if the PDF is in zoomed state.

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

You can find the code here.

你可以在这里找到代码。

#1


4  

So this post has been open for quite a while now but since it's the first entry on a Google search for "scroll pdf uiwebview" I thought I'd provide my take at this for future readers.

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

You can indeed scroll to a particular page in a PDF document using nothing but pure Java Script. I've posted sample code on our blog (http://apptech.next-munich.com/2011/02/pdf-in-uiwebview.html) but here's a short summary of what you need to do:

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

  1. Use the window.outerHeight DOM property to find the total height of the rendered PDF document.
  2. 使用window.outerHeight DOM属性查找呈现的PDF文档的总高度。

  3. Use the window.innerHeight DOM property to find the height of the browser window in browser coordinates.
  4. 使用window.innerHeight DOM属性在浏览器坐标中查找浏览器窗口的高度。

  5. Jump to the page using the window.scrollTo(x, y) function.
  6. 使用window.scrollTo(x,y)函数跳转到该页面。

There is one catch, though, that you cannot just device the outerHeight by the number of pages and jump to what you get. Instead, you will have to multiply by the innerHeight/webView.bounds.size.height ratio.

但是,有一个问题是,您不能只按页数设置outerHeight并跳转到您获得的内容。相反,您必须乘以innerHeight / webView.bounds.size.height比率。

#2


1  

I think that you'll have to load and display the PDF yourself using the PDF APIs rather than UIWebView. Here is an possible idea of how to simulate snapping scrolling to rectangular grid boundaries which may help you make the experience more like a UIWebView for your users.

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

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

iPhone sdk Cocoa Touch - 从父母UIView传递给孩子UIScrollview

#3


1  

I have seen your edit in question. Has anyone built a non-UIWebView-based PDF viewer (with source code)?

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

See my question.

看我的问题。

Reading PDF files as string through iPhone application

通过iPhone应用程序将PDF文件读取为字符串

It has functionality to display each pdf page in an image view. user can easily change pages. But the missing points are as follows.

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

  • user can not make any selection - as it is not text but an image
  • 用户无法进行任何选择 - 因为它不是文本而是图像

  • user can't find any text.
  • 用户找不到任何文字。

  • user can not zoom ( oh yes - you can put image view in scroll view for zooming functionality )
  • 用户无法缩放(哦,是的 - 您可以将图像视图放在滚动视图中以进行缩放功能)

#4


1  

The uiwebview commonly used to load pdf's has it's own scrollview object that you can make calls to. try something like this:

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

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

This will scroll the view for the pdf down 100 pixels. As for getting the pagenumber of the pdf, I can only imagine that javascript is what you need to take a look at. Or, If you simply know the number of pixels on each page of the pdf, then increment or decrement as necessary. :)

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

#5


1  

I have faced a similar problem, in which I had to scroll to particular page in PDF (which is displayed using UIWebView) on selection of a cell corresponding to that page in tableView (thumbnail tableview).

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

So I wrote a piece of code which allows you to scroll to particular page in PDF.

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

I am not using any javascript code. I am just keeping track of the zoom scale applied to the original PDF page each time and calculating the updated offset required to scroll to each page. So, this works even if the PDF is in zoomed state.

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

You can find the code here.

你可以在这里找到代码。