Считыватель PDF с CGPDFDocumentRef - PullRequest
0 голосов
/ 24 июля 2010

Я собираюсь сделать PDF-ридер и пробую два возможных решения:

  • UIWebView
  • CGPDFDocumentRef

Первый очень прост, но медленнее второго. Для второго я нашел учебник, и я могу просмотреть PDF, и я могу увеличить его двумя движениями пальцев. Но на данный момент я не могу сделать 2 вещи:

1) Просмотр PDF в альбомной ориентации, поддерживая правильные пропорции. 2) Сделайте увеличение / уменьшение масштаба с помощью двойного нажатия на экран.

Эти функции уже реализованы в UIWebView, но, как уже было сказано, он немного медленный и открывает весь документ PDF, а не только одну страницу (поэтому мне нужно разбить файл на несколько «одностраничных» файлов PDF «).

Кто-нибудь может мне помочь с некоторыми ссылками / ссылками / кодом о подобных проблемах?

Ответы [ 3 ]

3 голосов
/ 24 июля 2010

С помощью 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.

1 голос
/ 25 июля 2010

Точно, в примере, который я нашел, он использует 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));
}

Я практически все попробовал, но не могу найти хорошего решения!

0 голосов
/ 18 января 2011

Вы можете вызвать метод draw layer любого слоя вручную, сказав [yourLayer setNeedsDisplay]

...