I have used Quartz Core and CGPDF to show a zoomable PDF in my app for quite some time, but since Xcode 8 and trying to make my app compatible for iOS 9 and 10, the PDF-code seems to have broken. This is the code I have been using:
- (void)loadPDF
{
[self.scrollView removeFromSuperview];
[self.aContentView removeFromSuperview];
[self.tiledLayer removeFromSuperlayer];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *cachePath = [paths objectAtIndex:0];
NSURL *fileURL = [NSURL fileURLWithPath:[cachePath stringByAppendingPathComponent:@"Exmaple.pdf"]];
self.aDocumentRef = CGPDFDocumentCreateWithURL((CFURLRef)CFBridgingRetain(fileURL));
self.aPageRef = CGPDFDocumentGetPage(self.aDocumentRef, 1);
CGRect rect = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
self.tiledLayer = [CATiledLayer layer];
self.tiledLayer.delegate = nil;
self.tiledLayer.tileSize = rect.size;
self.tiledLayer.levelsOfDetail = 100;
self.tiledLayer.levelsOfDetailBias = 100;
self.tiledLayer.frame = rect;
self.aContentView = [[UIView alloc] initWithFrame:rect];
[self.aContentView.layer addSublayer:self.tiledLayer];
self.scrollView = [[UIScrollView alloc] initWithFrame:rect];
self.scrollView.delegate = self;
self.scrollView.contentSize = rect.size;
self.scrollView.maximumZoomScale = ZOOM_MAXIMUM;
[self.scrollView addSubview:self.aContentView];
[self.view addSubview:self.scrollView];
[self.aContentView setTag:ZOOM_VIEW_TAG];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
UITapGestureRecognizer *twoFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerTap:)];
[doubleTap setNumberOfTapsRequired:2];
[twoFingerTap setNumberOfTouchesRequired:2];
[self.aContentView addGestureRecognizer:doubleTap];
[self.aContentView addGestureRecognizer:twoFingerTap];
float minimumScale = [self.scrollView frame].size.width / [self.aContentView frame].size.width;
[self.scrollView setMinimumZoomScale:minimumScale];
[self.scrollView setZoomScale:minimumScale];
self.aContentView.translatesAutoresizingMaskIntoConstraints = YES;
self.scrollView.translatesAutoresizingMaskIntoConstraints = YES;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollViewLocal
{
return [self.scrollView viewWithTag:ZOOM_VIEW_TAG];
}
- (void)handleDoubleTap:(UIGestureRecognizer *)gestureRecognizer
{
float newScale = [self.scrollView zoomScale] * ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.scrollView zoomToRect:zoomRect animated:YES];
}
- (void)handleTwoFingerTap:(UIGestureRecognizer *)gestureRecognizer
{
float newScale = [self.scrollView zoomScale] / ZOOM_STEP;
CGRect zoomRect = [self zoomRectForScale:newScale withCenter:[gestureRecognizer locationInView:gestureRecognizer.view]];
[self.scrollView zoomToRect:zoomRect animated:YES];
}
- (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center
{
CGRect zoomRect;
zoomRect.size.height = [self.scrollView frame].size.height / scale;
zoomRect.size.width = [self.scrollView frame].size.width / scale;
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
- (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(self.aPageRef, kCGPDFCropBox, layer.bounds, 0, true));
CGContextDrawPDFPage(ctx, self.aPageRef);
}
The scroll view shows up but the page is blank. The PDF is loaded from the correct directory. Can anyone give me a hint of what I'm missing? Thanks!