简体   繁体   English

Objective-C Full UIView to PDF

[英]Objective-C Full UIView to PDF

I have this code here that takes my UIView in puts it into a PDF. 我在这里有这个代码,我把UIView放入PDF中。 My issue I am having is that my view is a detail view controller and is scrollable and the PDF only gets what inside the detail view controller at that time and not a full view, if I move around in the detail view, it will capture whatever part I am on, not the full thing. 我遇到的问题是我的视图是一个详细视图控制器并且是可滚动的,而PDF只获取当时详细视图控制器内部的内容而不是完整视图,如果我在详细视图中移动,它将捕获任何内容部分我在,而不是完整的事情。 Is what I am trying to do possible? 我正在尝试做什么?

- (IBAction)Share:(id)sender {

    NSMutableData *pdfData = [NSMutableData data];

    // Points the pdf converter to the mutable data object and to the UIView to be converted
    UIGraphicsBeginPDFContextToData(pdfData, spreadSheet.bounds, nil);
    UIGraphicsBeginPDFPage();
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();


    // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData

    [spreadSheet.layer renderInContext:pdfContext];

    // remove PDF rendering context
    UIGraphicsEndPDFContext();

    // Retrieves the document directories from the iOS device
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

    NSString* documentDirectory = [documentDirectories objectAtIndex:0];
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:@"test.pdf"];

    // instructs the mutable data object to write its context to a file on disk
    [pdfData writeToFile:documentDirectoryFilename atomically:YES];
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);


    UIActivityViewController * activityController = [[UIActivityViewController alloc] initWithActivityItems:@[pdfData] applicationActivities:nil];

    UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:activityController];

    [popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width - 36, 60, 0, 0)inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];

}

UPDATE UPDATE

I have been really struggling with this, I can't get the full view into a PDF, I have also been thinking of going to route of taking my NSMutableArray and my NSArray which is the data used in my UIView and try to covert that into a PDF but that sounds very time consuming to make format it nicely, unless someone knows of way to do that. 我一直在努力解决这个问题,我无法全面了解PDF,我一直在考虑采用我的NSMutableArray和我的NSArray的路线,这是我的UIView中使用的数据,并尝试将其转换为除非有人知道如何做到这一点,否则制作格式很简单,这听起来非常费时。 I guess I am confused on which route I should take. 我想我很困惑我应该采取哪条路线。

From this 由此

My issue I am having is that my view is a detail view controller and is scrollable and the PDF only gets what inside the detail view controller at that time and not a full view. 我遇到的问题是我的视图是一个详细视图控制器,并且可以滚动,PDF只能获取当时详细视图控制器内部的内容,而不是完整视图。

Looks like the problem is your content in view is scrollable and you pdf you creating is only capture the visible area. 看起来问题是您的视图中的内容是可滚动的,并且您创建的pdf只捕获可见区域。

Here is your problem 这是你的问题

UIGraphicsBeginPDFContextToData(pdfData, spreadSheet.bounds, nil); UIGraphicsBeginPDFContextToData(pdfData,spreadSheet.bounds,nil);

You need to fix it you need to give it the scrollable view (UITableView,UICollectionView or Scrollview) content size bounds here is how you do it. 您需要修复它,您需要为其提供可滚动视图(UITableView,UICollectionView或Scrollview)内容大小限制,这里是您如何做到这一点。

    -(NSData*)pdfDataFromTableViewContent
{
   NSMutableData *pdfData = [NSMutableData data];
   //The real size, not only the visible part use your scrollable view ((UITableView,UICollectionView or Scrollview))
   CGSize contentSize = self.tableView.contentSize;
   CGRect tableViewRealFrame = self.tableView.frame;
   //Size tableView to show the whole content
   self.tableView.frame = CGRectMake(0, 0, contentSize.width, contentSize.height);
   //Generate PDF (one page)
   UIGraphicsBeginPDFContextToData(pdfData,self.tableView.frame, nil);
   UIGraphicsBeginPDFPage();
   [self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
   UIGraphicsEndPDFContext();
   //Resize frame
   self.tableView.frame = tableViewRealFrame;
   return  pdfData;
}

The above code will generates one page. 上面的代码将生成一个页面。 For more pages use following code 有关更多页面,请使用以下代码

//MultiPage
CGRect mediaBox = self.tableView.frame;
CGSize pageSize = CGSizeMake(self.view.frame.size.width, 800);
UIGraphicsBeginPDFContextToData(pdfData, CGRectZero, nil);
CGContextRef pdfContext = UIGraphicsGetCurrentContext();
NSInteger currentPage = 0;
BOOL done = NO;
do {
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0.0, pageSize.width, pageSize.height), nil);
    CGContextTranslateCTM(pdfContext, 0, -(pageSize.height*currentPage));
    [self.view.layer renderInContext:pdfContext];
    if ((pageSize.height*(currentPage+1)) > mediaBox.size.height) done = YES;
    else currentPage++;
} while (!done);
UIGraphicsEndPDFContext();

You can also look into this working project ScrollViewToPDF . 您还可以查看这个工作项目ScrollViewToPDF It uses same scrollview's layer renderInContext but here PDF is created according to your requirement such as one page PDF or multiple page PDF. 它使用相同的scrollview层的renderInContext,但这里根据您的要求创建PDF,例如一页PDF或多页PDF。 It captures all visible as well as invisible part of scrollView 它捕获scrollView的所有可见部分和不可见部分

Rendering something into a context only renders what is currently in the view hierarchy. 将某些内容渲染到上下文中只会呈现视图层次结构中当前的内容。 That means that if you're using a UITableView or UICollectionView , not every cell that represents your data is in the hierarchy at any given time. 这意味着如果您使用的是UITableViewUICollectionView ,则在任何给定时间,并非每个代表您的数据的单元格都位于层次结构中。 If it were me I would try temporarily setting the view to have a massive frame so that everything would be in the hierarchy. 如果是我,我会尝试暂时设置视图以拥有一个巨大的框架,以便所有内容都在层次结构中。 If that didn't work I'd be writing a custom view that on request could layout everything for all the data and then reset to a more efficient layout after the rendering was complete. 如果这不起作用,我将编写一个自定义视图,根据请求可以布局所有数据的所有内容,然后在渲染完成后重置为更有效的布局。

Try following code to convert UIView to PDF. 尝试使用以下代码将UIView转换为PDF。

Note that the following method creates just a bitmap of the view; 请注意,以下方法仅创建视图的位图; it does not create actual typography. 它不会创建实际的排版。

-(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
{
    // Creates a mutable data object for updating with binary data, like a byte array
    NSMutableData *pdfData = [NSMutableData data];

    // Points the pdf converter to the mutable data object and to the UIView to be converted
    UIGraphicsBeginPDFContextToData(pdfData, aView.bounds, nil);
    UIGraphicsBeginPDFPage();
    CGContextRef pdfContext = UIGraphicsGetCurrentContext();


    // draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData

    [aView.layer renderInContext:pdfContext];

    // remove PDF rendering context
    UIGraphicsEndPDFContext();

    // Retrieves the document directories from the iOS device
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

    NSString* documentDirectory = [documentDirectories objectAtIndex:0];
    NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];

    // instructs the mutable data object to write its context to a file on disk
    [pdfData writeToFile:documentDirectoryFilename atomically:YES];
    NSLog(@"documentDirectoryFileName: %@",documentDirectoryFilename);
}

Also make sure you import: QuartzCore/QuartzCore.h 还要确保导入: QuartzCore/QuartzCore.h

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM