i'm going to make a PDF reader and i'm trying two possible solutions:
- UIWebView
- CGPDFDocumentRef
The first one is very simple, but is slower than the second one. For the second one, i found a tutorial and i can view a pdf and i can zoom it with the two fingers movement. But at the moment i can't do 2 things :
1) View the PDF in landscape mode, maintaining the correct proportions. 2) Do a zoom in / zoom out with the double tap on the screen.
Those functions are already implemented in the UIWebView, but how said before, it's a l开发者_如何学JAVAittle bit slow and it opens the entire PDF doc and not only a single page (so i need to split the file in many "one page pdf files").
Anyone can help me with some links/references/code about those kind of problems ?
With CGPDFDocumentRef
, you need to get each page with CGPDFDocumentGetPage
and then get the drawing transform with CGPDFPageGetDrawingTransform
and apply that to the CGContextRef
before you draw the page.
Putting the view with your PDF page in a UIScrollView will let you zoom in and out, if you enable zooming. You can also draw it with a zoom factor using
CGContextTranslateCTM (context, -sourceRect.origin.x * zoom, -sourceRect.origin.y * zoom);
CGContextScaleCTM (context, zoom, zoom);
But you'll still run into the issue that very complex PDF pages will be slow to render, and every time you call CGContextDrawPDFPage(context, page);
it has to render the entire page, such as when you change the zoom level. There are ways around this, such as drawing into a CATiledLayer.
Exactly, in the example that i found, he uses the CATiledLayer.
Here there is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
CFURLRef pdfURL = CFBundleCopyResourceURL(
CFBundleGetMainBundle(),
CFSTR(filename),
CFSTR("pdf"), NULL);
myDocumentRef = CGPDFDocumentCreateWithURL(pdfURL);
myPageRef = CGPDFDocumentGetPage(myDocumentRef, 1);
CGRect pageRect = CGRectMake(0, 0, 320, 480);
tiledLayer = [CATiledLayer layer];
tiledLayer.delegate = self;
tiledLayer.tileSize = CGSizeMake(1024.0, 1024.0);
tiledLayer.levelsOfDetail = 1000;
tiledLayer.levelsOfDetailBias = 1000;
tiledLayer.frame = pageRect;
myContentView = [[UIView alloc] initWithFrame:pageRect];
[myContentView.layer addSublayer:tiledLayer];
CGRect viewFrame = self.view.frame;
viewFrame.origin = CGPointZero;
scrollView = [[UIScrollView alloc] initWithFrame:viewFrame];
scrollView.delegate = self;
scrollView.contentSize = pageRect.size;
scrollView.maximumZoomScale = 100;
[scrollView addSubview:myContentView];
[self.view addSubview:scrollView];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return myContentView;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0);
CGContextFillRect(ctx, CGContextGetClipBoundingBox(ctx));
CGContextTranslateCTM(ctx, 0.0, layer.bounds.size.height);
CGContextScaleCTM(ctx, 1.0, -1.0);
CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(myPageRef, kCGPDFCropBox, layer.bounds, 0, true));
CGContextDrawPDFPage(ctx, myPageRef);
}
This part works great, but if i want to introduce the landscape mode, i need to modify this part:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if( (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight)){
//SOMETHING TO DO FOR LANDSCAPE MODE
}
else if((interfaceOrientation == UIInterfaceOrientationPortrait)){
//SOMETHING TO DO TO RESTORE TO PORTRAIT
}
// Return YES for supported orientations
return ((interfaceOrientation == UIInterfaceOrientationPortrait) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
I tried pratically everything, but i can't find a good solution !
you can call draw layer method of any layer manually by saying [yourLayer setNeedsDisplay]
精彩评论