0

我要制作一个 PDF 阅读器,我正在尝试两种可能的解决方案:

  • UIWebView
  • CGPDFDocumentRef

第一个非常简单,但比第二个慢。对于第二个,我找到了一个教程,我可以查看 pdf,我可以用两根手指移动来缩放它。但目前我不能做两件事:

1) 以横向模式查看 PDF,保持正确的比例。2)在屏幕上双击进行放大/缩小。

这些功能已经在 UIWebView 中实现了,但是之前怎么说呢,它有点慢,它打开了整个 PDF 文档,而不仅仅是一个页面(所以我需要将文件拆分为许多“单页 pdf 文件”)。

任何人都可以帮助我提供一些关于这类问题的链接/参考/代码?

4

3 回答 3

3

使用CGPDFDocumentRef,您需要使用 获取每个页面,CGPDFDocumentGetPage然后使用 获取绘图转换CGPDFPageGetDrawingTransform并将其应用于CGContextRef绘制页面之前。

如果启用缩放,将带有 PDF 页面的视图放在 UIScrollView 中可以让您放大和缩小。您还可以使用缩放因子绘制它

    CGContextTranslateCTM (context, -sourceRect.origin.x * zoom, -sourceRect.origin.y * zoom);
    CGContextScaleCTM (context, zoom, zoom);

但是您仍然会遇到非常复杂的 PDF 页面渲染速度很慢的问题,并且每次调用CGContextDrawPDFPage(context, page);它都必须渲染整个页面,例如当您更改缩放级别时。有一些方法可以解决这个问题,例如绘制到 CATiledLayer。

于 2010-07-24T16:18:44.060 回答
1

确切地说,在我发现的示例中,他使用了 CATiledLayer。
这是我的代码:

- (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);
}

这部分效果很好,但是如果我想引入横向模式,我需要修改这部分:

- (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));
}

我几乎尝试了一切,但我找不到一个好的解决方案!

于 2010-07-24T20:28:21.153 回答
0

您可以通过说 [yourLayer setNeedsDisplay] 手动调用任何图层的绘制图层方法

于 2011-01-18T13:46:18.127 回答