Генерация PDF из UIScrollView + iphone - PullRequest
3 голосов
/ 11 марта 2011

Я хочу создать PDF-файл UIScrollView с размером содержимого около 320 * 2000.Если я использую текущий контекст графического изображения для захвата слоя вида прокрутки, то он захватывает только видимую часть вида прокрутки, а не весь слой этого вида прокрутки.

Я использую следующий код:

-(void)CreatePdf:(id)sender
{

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *saveDirectory = [paths objectAtIndex:0];
    NSString *saveFileName = @"myPDF.pdf";
    [self writePDFAma];
    CGRect arect=CGRectMake(0, 0, 768, 1024);

    CreatePDFFileAma(arect, nil);
}



-(void) writePDFAma
{
    UIImage *image;
    NSData *data;
    UIAlertView *successAlert;
    UIAlertView *failureAlert;
    //  
    NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //  // This should be our documents directory
    NSString *saveDiirectory = [documentPath objectAtIndex:0];
    //  // Our PDF is named 'Example.pdf'
    NSString *saveFileName = @"FormImage2.JPG";
    //  // Create the full path using our saveDirectory and saveFileName
    NSString *finalPath = [saveDiirectory stringByAppendingPathComponent:saveFileName];
    //NSLog(@"%@",finalPath);
    CGSize asize=CGSizeMake(_scrollview.frame.size.width, _scrollview.frame.size.height);
    //NSLog(@"%d..%d",mainViewAma.frame.size.width, mainViewAma.frame.size.height);
    UIGraphicsBeginImageContext(asize);
        [[_scrollview layer] renderInContext:UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    data = UIImageJPEGRepresentation(image, 1.0);

    BOOL catch;
    if(!catch){
        if ([[NSFileManager defaultManager] createFileAtPath:finalPath contents:data attributes:nil])
        {
            successAlert = [[UIAlertView alloc] initWithTitle:@"Success" message:@"Doodle was successfully saved to the Photo Library." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
            //[successAlert show];
            [successAlert release];
        } else {
            failureAlert = [[UIAlertView alloc] initWithTitle:@"Failure" message:@"Failed to save doodle to the Photo Library." delegate:self cancelButtonTitle:@"Close" otherButtonTitles:nil];
            //[failureAlert show];
            [failureAlert release];
        }

    }

}


void CreatePDFFileAma (CGRect pageRect, const char *filename)
{
    // This code block sets up our PDF Context so that we can draw to it
    //some code here
    CGContextRef pdfContext;
    CFURLRef url;
    CFMutableDictionaryRef myDictionary = NULL;
    NSArray *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //  // This should be our documents directory
    NSString *saveDirectory = [documentPath objectAtIndex:0];
    //  // Our PDF is named 'Example.pdf'



    //NSString *saveFileName = @"PDFForm2.pdf";



    //  // Create the full path using our saveDirectory and saveFileName
    NSString *finalPath = [saveDirectory stringByAppendingPathComponent:saveFileName];
    NSURL * aurl=[[NSURL alloc]initFileURLWithPath:finalPath];
    url=(CFURLRef)aurl;
    // This dictionary contains extra options mostly for 'signing' the PDF
    myDictionary = CFDictionaryCreateMutable(NULL, 0,
                                             &kCFTypeDictionaryKeyCallBacks,
                                             &kCFTypeDictionaryValueCallBacks);
    CFDictionarySetValue(myDictionary, kCGPDFContextTitle, CFSTR("AMA FORM PDF"));
    CFDictionarySetValue(myDictionary, kCGPDFContextCreator, CFSTR("My Name2"));
    // Create our PDF Context with the CFURL, the CGRect we provide, and the above defined dictionary
    pdfContext = CGPDFContextCreateWithURL (url, &pageRect, myDictionary);
    // Cleanup our mess
    CFRelease(myDictionary);
    CFRelease(url);
    // Starts our first page
    CGContextBeginPage (pdfContext, &pageRect);

    // Draws a black rectangle around the page inset by 50 on all sides
    CGContextStrokeRect(pdfContext, CGRectMake(50, 50, 768, 1024));

    // This code block will create an image that we then draw to the page
    CGImageRef image;
    CGDataProviderRef provider;
    CFURLRef pictureURL;
    documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //  // This should be our documents directory
    saveDirectory = [documentPath objectAtIndex:0];
    NSString *saveFileName2 = @"FormImage2.JPG";
    //  // Create the full path using our saveDirectory and saveFileName
    NSString *finalPath2 = [saveDirectory stringByAppendingPathComponent:saveFileName2];
    NSURL * aurl2=[[NSURL alloc]initFileURLWithPath:finalPath2];
    pictureURL=(CFURLRef)aurl2;
    provider = CGDataProviderCreateWithURL (pictureURL);
    CFRelease (pictureURL);
    image = CGImageCreateWithJPEGDataProvider(provider, NULL, TRUE, kCGRenderingIntentDefault); //DataProvider (, NULL, true, kCGRenderingIntentDefault);
    CGDataProviderRelease (provider);
    CGContextDrawImage (pdfContext, CGRectMake(0, 0,768, 1024),image);
    CGImageRelease (image);
    CGContextEndPage (pdfContext);
    // We are done with our context now, so we release it
    CGContextRelease (pdfContext);
}

Ответы [ 3 ]

7 голосов
/ 23 марта 2011

Хех, ребята, я подготовил некоторую базу кода, используя примеры, доступные в сети, для создания PDF из UIScrollView. Нам нужно понять две вещи:

1) количество страниц 2) содержимое scrollview

Я создал вид прокрутки размер содержимого (10 * 910).так что у него 10 страниц. .Это для iPad.

вот база кода

- (void) createPDF
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *directroyPath = nil;
    directroyPath = [documentsDirectory stringByAppendingPathComponent:@"PDF"];
    NSString *filePath = [directroyPath stringByAppendingPathComponent:@"test.pdf"];
    // check for the "PDF" directory
    NSError *error;
    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {

    } else {
        [[NSFileManager defaultManager] createDirectoryAtPath:directroyPath
                                  withIntermediateDirectories:NO
                                                   attributes:nil
                                                        error:&error];
    }   

     CGContextRef pdfContext = [self createPDFContext:myScrollView.bounds path:(CFStringRef)filePath];
    NSLog(@"PDF Context created");

    for (int i = 0 ; i< 10 ; i++)
    {

        // page 1
        CGContextBeginPage (pdfContext,nil); 

        //turn PDF upsidedown   
        CGAffineTransform transform = CGAffineTransformIdentity;    
        transform = CGAffineTransformMakeTranslation(0, (i+1) * 910);   
        transform = CGAffineTransformScale(transform, 1.0, -1.0);   
        CGContextConcatCTM(pdfContext, transform);  

        //Draw view into PDF
        [myScrollView.layer renderInContext:pdfContext];    
        CGContextEndPage (pdfContext);          
        [myScrollView setContentOffset:CGPointMake(0, (i+1) * 910) animated:NO];

    }
    CGContextRelease (pdfContext);
}

- (CGContextRef) createPDFContext:(CGRect)inMediaBox path:(CFStringRef) path    
{   
    CGContextRef myOutContext = NULL;   
    CFURLRef url;   
    url = CFURLCreateWithFileSystemPath (NULL, path,                                         
                                         kCFURLPOSIXPathStyle,                                       
                                         false);

    if (url != NULL) {      
        myOutContext = CGPDFContextCreateWithURL (url, 
                                                  &inMediaBox,                                                
                                                  NULL);        
        CFRelease(url);     
    }   
    return myOutContext;
}
5 голосов
/ 10 января 2014

Я придумал другое решение:

-(NSData*)pdfDataFromTableViewContent{
   NSMutableData *pdfData = [NSMutableData data];
   //The real size, not only the visible part
   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;}

Размер кадра соответствует всему содержимому scrollView, захватывает его в graphicsContext, возвращает размер кадра обратно.

Верхний код генерирует одну страницу.
Для большего количества страниц я использую в основном это:

//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();
0 голосов
/ 12 марта 2011

возможно ли увидеть ваш пример кода, пожалуйста, я пытаюсь сделать то же самое точно.

Вы можете отправить исходный код здесь, спасибо за то, что вы были бы очень щедрыми dott.marco@mac.com

В любом случае для вашей проблемы это может помочь:

Вы захватываете видимое содержимое только потому, что размер вашего прокрутки соответствует только видимому содержимому, что и должно быть.Вам нужно изменить размер прокрутки, чтобы он соответствовал содержимому, которое необходимо захватить, прежде чем начинать код рисования, используя что-то вроде этого:

Code: self.scrollView.frame = CGRectMake (0, 0, "ширина вашего контента здесь"," высота вашего контента здесь ");После того, как вы закончите рисование, убедитесь, что изменили размер представления прокрутки назад, в этом случае к представлению контейнера:

Код: self.scrollView.frame = CGRectMake (0, 0, self.view.frame.size).width, self.view.frame.size.height);

...