【发布时间】:2009-12-18 12:06:32
【问题描述】:
可以使用 JavaScript 设置UIWebView 的像素 y 偏移量,例如:
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"scrollTo(0, %d)", offset]];
那么有没有办法得到:
- Web 视图中 PDF 单个页面的像素高度?
- 页面之间的间隙大小?
这些信息可以从UIWebView 获得还是可以通过其他方式计算?
我在想,如果我有页面数(通过 CGPDFDocumentGetNumberOfPages)、页面之间的像素高度差距或单个页面的像素高度,我可以计算 offset 以与 JavaScript 一起使用称呼。然后我只需连接一个UIButton 或UISlider 在页面之间移动。
编辑我
我有一个解决方案,但它使用UIWebDocumentView,UIWebView 的私有子视图。
我创建了一个名为PDFViewerViewController的视图控制器,它是WebViewerViewController的子类,它本身就是一个包含UIToolbar、UIWebView的视图控制器,并且符合UIWebViewDelegate协议。
在调用 Web 视图委托方法 -webViewDidFinishLoad: 后,我的 PDFViewerViewController 计算有关封闭 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)]];
}
一些观察
偏移量计算不是完美的页面。如果 PDF 文档不是 8.5 x 11(例如 A4),那么偏移误差会更快地恶化。
通过触摸拖动滚动浏览 Web 视图时,
self.currentPage属性不会更新。可能会拖几页,然后触摸工具栏上的左箭头或右箭头会导致偏移量意外移动到上一页。此解决方案使用
UIWebDocumentView,这是私有的,可能会导致应用被拒绝。
我想我会向 Apple 提出功能增强请求。
有没有人构建了一个非UIWebView-based PDF 查看器(带有源代码)?
【问题讨论】:
-
如果这不起作用,您是否尝试将 PDF 放入 iframe(iPhone 文档不鼓励使用标准框架,但 iframe 可能没问题)并在父 HTML 文档中调用 JavaScript?
-
我不认为可以从 Web 视图中获得页数。你的建议似乎没问题。尝试设置 scalesPagesToFit=YES 然后页面高度应该是浏览器视图/框架高度。
-
我想当用户更改缩放级别时,您会感到沮丧!棘手。当 PDF 嵌入 iframe 时,您是否尝试过检查 DOM 模型——尽管这可能会开始转向非公共 API 使用?
-
如果我在
-webViewDidFinishLoad:中记录 Web 视图的框架和边界,我得到的值不能反映内容的实际高度。 (例如,对于一个四页的 PDF,对于纵向显示的 PDF,我应该得到超过 456 像素的东西。) -
啊,是的,这是 Apple 添加的另一个令人着迷的东西。 JavaScript 中的坐标反映的坐标好像 iPhone 屏幕是桌面显示器尺寸而不是 iPhone 尺寸。我想他们这样做是为了最大限度地提高与桌面的兼容性。如果没有额外的概念混搭使其看起来像桌面的坐标系,我找不到在 JavaScript 中获取 iPhone 屏幕坐标的方法。我认为您需要与 Apple 的某个人成为朋友才能获得使用私有 API 或其他东西的许可。
标签: iphone pdf uiwebview cgpdfdocument