I am creating a PDFViewer application. I have set the autoScale Property of the PDFViewer to true, so that it the view expands to the width of the screen. Works fine with large PDF documents. But when the document is a single page document, the page automatically scrolls down to the end of the page, instead of starting with the beginning. I just cant understand the root cause of it. What am I missing here?
I think this is a bug in PDFView.
As workaround I suggest to manually scroll top the top:
self.pdfView.document = pdfDocument;
NSPoint pt = NSMakePoint(0.0, [self.pdfView.documentView bounds].size.height);
[self.pdfView.documentView scrollPoint:pt];
Bug Reporter
rdar://37942090: PDFview scrolls to bottom of the page in single page document.
- (void)goToRect:(PDFRect)rect onPage:(PDFPage *)page;
... I assume CGRectMake(0,0,1,1) may work –
Nariko This is what I did, it's a bit hacky
if let scrollView = pdfView.subviews.first as? UIScrollView {
scrollView.contentOffset.y = 0.0
}
I think this is a bug in PDFView.
As workaround I suggest to manually scroll top the top:
self.pdfView.document = pdfDocument;
NSPoint pt = NSMakePoint(0.0, [self.pdfView.documentView bounds].size.height);
[self.pdfView.documentView scrollPoint:pt];
Bug Reporter
rdar://37942090: PDFview scrolls to bottom of the page in single page document.
- (void)goToRect:(PDFRect)rect onPage:(PDFPage *)page;
... I assume CGRectMake(0,0,1,1) may work –
Nariko I propose this solution for scrolling to top of first page (it works on iOS 11.3):
if let document = pdfView.document,
let firstPage = document.page(at: 0)
{
let firstPageBounds = firstPage.bounds(for: pdfView.displayBox)
pdfView.go(to: CGRect(x: 0, y: firstPageBounds.height, width: 1.0, height: 1.0), on: firstPage)
}
pdfView.autoScale = true
. The pdf always opens at the bottom of the second page –
Coast autoScale
doesn't matter) and it scrolls to the top of the page. But in case you want to scroll a little bit further as a user would be able to do (so that the page's top shadow is visible), @aaron-halvorsen's anwser seems to be the way to go. –
Cobden Looks like the go
command needs to be done on the next run through the run loop to work reliably:
DispatchQueue.main.async
{
guard let firstPage = pdfView.document?.page(at: 0) else { return }
pdfView.go(to: CGRect(x: 0, y: Int.max, width: 0, height: 0), on: firstPage)
}
Tested on iOS 12
Expanding on Petro's answer, I had some issues with rotated pages and cropped pages, but this seems to work universally. I actually tested it on rotated pages, along with an annotation in the corner to verify that I was selecting the right corner:
guard let firstPage = pdfView!.document?.page(at: 0) else {
return;
}
let firstPageBounds = firstPage.bounds(for: pdfView!.displayBox)
switch (firstPage.rotation % 360) {
case 0:
topLeftX = firstPageBounds.minX
topLeftY = firstPageBounds.maxY
case 90:
topLeftX = firstPageBounds.minX
topLeftY = firstPageBounds.minY
case 180:
topLeftX = firstPageBounds.maxX
topLeftY = firstPageBounds.minY
case 270:
topLeftX = firstPageBounds.maxX
topLeftY = firstPageBounds.maxY
default:
print ("Invalid rotation value, not divisible by 90")
}
pdfView!.go(to: CGRect(x: topLeftX, y: topLeftY, width: 1.0, height: 1.0), on: firstPage)
I was loading the document in viewDidLoad, then I moved it to viewDidAppear, and it worked for me.
viewDidLoad
does not seem to be the right place for modifying screen content, because layouts have not been processed yet... No need to set any offsets or frames on PDFView, when you first set its document in viewDidAppear
–
Melisenda The rotation of the PDFPage matters! This is the Objective-C version of Oded:
- (void)scrollToTopOfPage:(PDFPage *)page {
CGRect pageBounds = [page boundsForBox:self.displayBox];
CGFloat topLeftX = 0;
CGFloat topLeftY = 0;
switch (page.rotation % 360) {
case 0:
topLeftX = CGRectGetMinX(pageBounds);
topLeftY = CGRectGetMaxY(pageBounds);
break;
case 90:
topLeftX = CGRectGetMinX(pageBounds);
topLeftY = CGRectGetMinY(pageBounds);
break;
case 180:
topLeftX = CGRectGetMaxX(pageBounds);
topLeftY = CGRectGetMinY(pageBounds);
break;
case 270:
topLeftX = CGRectGetMaxX(pageBounds);
topLeftY = CGRectGetMaxY(pageBounds);
break;
default:
break;
}
[self goToRect:CGRectMake(topLeftX, topLeftY, 1, 1) onPage:page];
}
if let document = PDFDocument(url: viewModel.url) {
pdfView.document = document
// avoid iOS autoscale issue
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
self?.pdfView.autoScales = true
}
}
I used the work around to define the autoScales
property a bit after the loading of the document. The first page is nicely fit on top then.
For Objective-C use:
PDFPage *firstPage = [pdfView.document pageAtIndex:0];
CGRect firstPageBounds = [firstPage boundsForBox:pdfView.displayBox];
[pdfView goToRect:CGRectMake(0, firstPageBounds.size.height, 1, 1) onPage:firstPage];
© 2022 - 2024 — McMap. All rights reserved.