有没有办法以编程方式滚动到 UIWebView 中的 PDF 页面? [英] Is there a way to programmatically scroll to a PDF page within a UIWebView?

查看:12
本文介绍了有没有办法以编程方式滚动到 UIWebView 中的 PDF 页面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

那么有没有办法得到:

  1. Web 视图中 PDF 单个页面的像素高度?
  2. 页面之间的间隙大小?

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

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

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

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.

编辑我

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

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

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

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 在调用 Web 视图委托方法 -webViewDidFinishLoad: 后计算有关封闭 Web 视图和 PDF 数据的一些信息.

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

此信息用于计算通过 JavaScript 提供给 Web 视图的近似每页偏移量.

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

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),那么偏移误差会更快地恶化.

  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.

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

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.

本方案使用UIWebDocumentView,是私有的,可能会导致应用被拒绝.

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

我想我会向 Apple 提出功能增强请求.

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

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

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

推荐答案

所以这篇文章已经打开了很长一段时间,但因为它是谷歌搜索scroll pdf uiwebview"的第一个条目,我想我会提供我对未来的读者的看法.

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.

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

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:

  1. 使用 window.outerHeight DOM 属性查找呈现的 PDF 文档的总高度.
  2. 使用 window.innerHeight DOM 属性在浏览器坐标中查找浏览器窗口的高度.
  3. 使用 window.scrollTo(x, y) 函数跳转到页面.

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

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.

这篇关于有没有办法以编程方式滚动到 UIWebView 中的 PDF 页面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆