Note that there are some explanatory texts on larger screens.

plurals
  1. POIs there a way to programmatically scroll to a PDF page within a UIWebView?
    primarykey
    data
    text
    <p>It is possible to use JavaScript to set the pixel y-offset of a <code>UIWebView</code>, e.g.:</p> <pre><code>[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"scrollTo(0, %d)", offset]]; </code></pre> <p>So is there a way to get:</p> <ol> <li>The pixel height of an individual page of a PDF within the web view?</li> <li>The size of the gap between pages?</li> </ol> <p>Is this information available from the <code>UIWebView</code> or can it be calculated through alternative means?</p> <p>I'm thinking that if I have the number of pages (via <a href="http://developer.apple.com/mac/library/DOCUMENTATION/GraphicsImaging/Reference/CGPDFDocument/Reference/reference.html#//apple_ref/doc/uid/TP30000958-CH1g-F17191" rel="noreferrer"><code>CGPDFDocumentGetNumberOfPages</code></a>), the pixel height gap between pages, or the pixel height of an individual page, I can calculate the <code>offset</code> to use with the JavaScript call. Then I just wire up a <code>UIButton</code> or <code>UISlider</code> to move between pages.</p> <hr> <p><strong>EDIT I</strong></p> <p>I have a solution, but it uses <code>UIWebDocumentView</code>, a private subview of <code>UIWebView</code>.</p> <p>I create a view controller called <code>PDFViewerViewController</code>, which is a subclass of <code>WebViewerViewController</code>, which itself is a view controller that contains a <code>UIToolbar</code>, a <code>UIWebView</code>, and conforms to the <code>UIWebViewDelegate</code> protocol.</p> <p>My <code>PDFViewerViewController</code> calculates some information about the enclosing web view and the PDF data, after the web view delegate method <code>-webViewDidFinishLoad:</code> gets called. </p> <p>This information is used to calculate an approximate per-page offset that gets fed to the web view via JavaScript.</p> <p><strong>PDFViewerViewController.h</strong></p> <pre><code>#import &lt;UIKit/UIKit.h&gt; #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 </code></pre> <p><strong>PDFViewerViewController.m</strong></p> <pre><code>#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)]]; } </code></pre> <p><strong>Some observations</strong></p> <ol> <li><p>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.</p></li> <li><p>The <code>self.currentPage</code> 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.</p></li> <li><p>This solution uses <code>UIWebDocumentView</code>, which is private and may likely cause app rejection.</p></li> </ol> <p>I think I'll file a feature enhancement request with Apple. </p> <p>Has anyone built a non-<code>UIWebView</code>-based PDF viewer (with source code)?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload