Рендеринг PDF в Apple TV TVOS

Я работаю над дополнением к моему приложению tvOS, которое позволит просматривать PDF-файлы, хранящиеся в приложении. Однако без UIWebView я не знаю, как это сделать. Я задал вопрос в других местах, и меня встретили ссылкой на многословный и беспомощный документ Apple об API, которые можно использовать, и даже здесь на него есть ссылка (CGPDFPage), но нет реального руководства о том, как реализовать это, Кто-нибудь успешно делал это на tvOS, и если да, не могли бы вы помочь мне начать этот процесс?

3 ответа

Решение

Ниже приведен код, который я написал и протестировал в tvOS. Обратите внимание, что это в Objective-c.

Я создал две функции для выполнения этой работы и одну вспомогательную функцию для отображения изображений PDF в UIScrollView. Первый откроет PDF документ с URL. Веб-URL был использован. Локальный файл также может быть использован в этом примере.

Существует также вспомогательная функция для открытия документа из локального файла.

Вторая функция рендерит документ PDF в контекст. Я решил отобразить контекст, создав из него изображение. Есть и другие способы обработки контекста.

Открыть документ довольно просто, поэтому в коде нет комментариев. Рендеринг документа немного более сложен, поэтому есть комментарии, объясняющие эту функцию.

Полная заявка ниже.

- (CGPDFDocumentRef)openPDFLocal:(NSString *)pdfURL {
    NSURL* NSUrl = [NSURL fileURLWithPath:pdfURL];

    return [self openPDF:NSUrl];
}

- (CGPDFDocumentRef)openPDFURL:(NSString *)pdfURL {
    NSURL* NSUrl= [NSURL URLWithString:pdfURL];

    return [self openPDF:NSUrl];
}

- (CGPDFDocumentRef)openPDF:(NSURL*)NSUrl {
    CFURLRef url = (CFURLRef)CFBridgingRetain(NSUrl);

    CGPDFDocumentRef myDocument;
    myDocument = CGPDFDocumentCreateWithURL(url);
    if (myDocument == NULL) {
        NSLog(@"can't open %@", NSUrl);
        CFRelease (url);
        return nil;
    }
    CFRelease (url);

    if (CGPDFDocumentGetNumberOfPages(myDocument) == 0) {
        CGPDFDocumentRelease(myDocument);
        return nil;
    }

    return myDocument;
}
- (void)drawDocument:(CGPDFDocumentRef)pdfDocument
{
    // Get the total number of pages for the whole PDF document
    int  totalPages= (int)CGPDFDocumentGetNumberOfPages(pdfDocument);
    NSMutableArray *pageImages = [[NSMutableArray alloc] init];

    // Iterate through the pages and add each page image to an array
    for (int i = 1; i <= totalPages; i++) {
        // Get the first page of the PDF document
        CGPDFPageRef page = CGPDFDocumentGetPage(pdfDocument, i);
        CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);

        // Begin the image context with the page size
        // Also get the grapgics context that we will draw to
        UIGraphicsBeginImageContext(pageRect.size);
        CGContextRef context = UIGraphicsGetCurrentContext();

        // Rotate the page, so it displays correctly
        CGContextTranslateCTM(context, 0.0, pageRect.size.height);
        CGContextScaleCTM(context, 1.0, -1.0);
        CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(page, kCGPDFMediaBox, pageRect, 0, true));

        // Draw to the graphics context
        CGContextDrawPDFPage(context, page);

        // Get an image of the graphics context
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        [pageImages addObject:image];
    }
    // Set the image of the PDF to the current view
    [self addImagesToScrollView:pageImages];
}

-(void)addImagesToScrollView:(NSMutableArray*)imageArray {
    int heigth = 0;
    for (UIImage *image in imageArray) {
        UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
        imgView.frame=CGRectMake(0, heigth, imgView.frame.size.width, imgView.frame.size.height);
        [_scrollView addSubview:imgView];
        heigth += imgView.frame.size.height;
    }
}

И чтобы связать все это вместе, вы можете сделать это:

CGPDFDocumentRef pdfDocument = [self openPDFURL:@"http://www.guardiansuk.com/uploads/accreditation/10testing.pdf"];
[self drawDocument:pdfDocument];

Обратите внимание, что я использую случайный PDF, который был доступен бесплатно в Интернете. Я столкнулся с некоторыми проблемами с URL-адресами https, но я уверен, что это можно решить, и это на самом деле не связано с вопросом открытия PDF.

Документация по tvOS содержит раздел о создании, просмотре и преобразовании PDF-документов, поэтому я думаю, что он содержит необходимые вам функции.

На этой странице много примеров кода, но вот код, который я использую на iOS для той же цели. Это должно работать на tvOS, но у меня нет способа проверить это:

func imageForPDF(URL: NSURL, pageNumber: Int, imageWidth: CGFloat) -> UIImage {
    let document = CGPDFDocumentCreateWithURL(URL)
    let page = CGPDFDocumentGetPage(document, pageNumber)
    var pageRect = CGPDFPageGetBoxRect(page, .MediaBox)
    let scale = imageWidth / pageRect.size.width
    pageRect.size = CGSizeMake(pageRect.size.width * scale, pageRect.size.height * scale)
    pageRect.origin = CGPointZero

    UIGraphicsBeginImageContext(pageRect.size)
    let ctx = UIGraphicsGetCurrentContext()
    CGContextSetRGBFillColor(ctx, 1.0, 1.0, 1.0, 1.0) // White background
    CGContextFillRect(ctx, pageRect)
    CGContextSaveGState(ctx)

    // Rotate the PDF so that it’s the right way around
    CGContextTranslateCTM(ctx, 0.0, pageRect.size.height)
    CGContextScaleCTM(ctx, 1.0, -1.0)
    CGContextConcatCTM(ctx, CGPDFPageGetDrawingTransform(page, .MediaBox, pageRect, 0, true))

    CGContextDrawPDFPage(ctx, page)
    CGContextRestoreGState(ctx)

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}

Это ответ @jbg в Swift 5

`

Другие вопросы по тегам