Rendering PDF in Apple TV tvOS

前端 未结 2 1114
悲哀的现实
悲哀的现实 2021-02-14 17:23

I am working on an addition to my tvOS app that would allow viewing of PDFs stored in the app. However, without UIWebView, I\'m at a loss on how to do this. I\'ve asked questi

相关标签:
2条回答
  • 2021-02-14 17:45

    The tvOS documentation contains a section on creating, viewing and transforming PDF documents so I think it contains the functionality you need.

    There’s lots of example code on that page, but here’s some code I use on iOS for the same purpose. It should work on tvOS, but I don’t have a way to test it:

    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
    }
    
    0 讨论(0)
  • 2021-02-14 17:53

    Below is some code that I wrote and tested in tvOS. Note that this is in Objective-c.

    I've created two functions to do the job, and one helper function to display the PDF images in a UIScrollView. The first one will open the PDF document from a URL. A web URL was used. A local file could also be used in this sample.

    There is also a helper function to open a document from a local file.

    The second function renders the PDF document to a context. I chose to display the context by creating an image from it. There are other ways of handling the context too.

    Opening the document is fairly straight forward, so there are no comments in the code for that. Rendering the document is slightly more involved, and so there are comments explaining that function.

    The complete application is below.

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

    And to tie it all together, you can do this:

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

    Note that I'm using a random PDF that was available for free on the web. I ran into some problems with https URLs, but I'm sure this can be resolved, and it's not actually related to the PDF opening question.

    0 讨论(0)
提交回复
热议问题