2013-04-16 4 views
6

Mam UITableView, który jest wypełniony pewnymi danymi, ale ponieważ zawiera dane, które są bardziej komórkowe niż widoczny obszar ekranu, udało mi się uzyskać tylko migawkę to, chcę wiedzieć, czy istnieje inny sposób mogę dostać całą migawkę tableview w pdf..this co próbowałem dziękiJak uzyskać migawkę UITableView w formacie PDF

- (IBAction)clickMe:(id)sender 
{ 
    UIView *viewToRender = self.myTableView; 
    CGPoint contentOffset = self.myTableView.contentOffset; 

    UIGraphicsBeginImageContext(viewToRender.bounds.size); 

    CGContextRef ctx = UIGraphicsGetCurrentContext(); 

    // KEY: need to translate the context down to the current visible portion of the tablview 
    CGContextTranslateCTM(ctx, 0, -contentOffset.y); 

    [viewToRender.layer renderInContext:ctx]; 

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIImageView *myImage=[[UIImageView alloc]initWithImage:image]; 

    UIGraphicsEndImageContext(); 

    [self createPDFfromUIViews:myImage saveToDocumentsWithFileName:@"PDF Name"]; 

} 



- (void)createPDFfromUIViews:(UIView *)myImage saveToDocumentsWithFileName:(NSString *)string 
{ 
    NSMutableData *pdfData = [NSMutableData data]; 

    UIGraphicsBeginPDFContextToData(pdfData, myImage.bounds, nil); 
    UIGraphicsBeginPDFPage(); 
    CGContextRef pdfContext = UIGraphicsGetCurrentContext(); 


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

    [myImage.layer renderInContext:pdfContext]; 

    // remove PDF rendering context 
    UIGraphicsEndPDFContext(); 
    NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); 

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

    NSLog(@"%@",documentDirectoryFilename); 
    [pdfData writeToFile:documentDirectoryFilename atomically:YES]; 
} 

Odpowiedz

14
UIGraphicsBeginImageContext(self.myTableView.contentSize); 
[self.myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
[self.myTableView.layer renderInContext:UIGraphicsGetCurrentContext()]; 

int rows = [self.myTableView numberOfRowsInSection:0]; 
int numberofRowsInView = 4; 
for (int i =0; i < rows/numberofRowsInView; i++) { 
    [self.myTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:(i+1)*numberofRowsInView inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
    [self.myTableView.layer renderInContext:UIGraphicsGetCurrentContext()]; 

} 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIImageView *myImage=[[UIImageView alloc]initWithImage:image]; 
UIGraphicsEndImageContext(); 


[self createPDFfromUIViews:myImage saveToDocumentsWithFileName:@"PDF Name"]; 

nie wiem, ale ten kod działa jak czar dla mnie ..

+1

Nice! Nie znałem tego, powinieneś zaakceptować własną odpowiedź, – Jano

+1

Cześć, dzięki za ten kod. Próbowałem to zrobić. Nie jestem pewien, co robię źle. Użyłem tego kodu, ale wydaje się, że nie działa po przewinięciu tableview. Czy możesz proszę sprawdzić moje pytanie i podać swoje przemyślenia proszę -http: //stackoverflow.com/questions/17771112/ios-rendering-uitableview-into-pdf Byłoby naprawdę wdzięczne. – applefreak

+0

Dzięki, naprawdę użyteczne, również nie zapomnij, że UITableView odziedziczył z UIScrollView, więc możliwe do zrobienia coś takiego: CGFloat screensInTable = self.tableView.contentSize.height/self.tableView.frame.size.height; dla (int i = 1; i

2

Brak Offscreen komórki, ponieważ są one recyklingowi, jak tylko przejdź z widocznego ekranu. Zamiast zrzutu ekranu UITableView, powinieneś rozważyć utworzenie wersji PDF przy użyciu Core Text. Być może dostosujesz to example.

+0

Dzięki za information..i dostał mały kawałek kodu, który pomaga mi zrobić proces snapshot, spojrzeć na mojego kodu – vin

1

podstawie odpowiedzi Vin jest (może być również stosowany do snapshotting UIScrollViews):

UIGraphicsBeginPDFContextToData(pdfData, CGRectMakeWithSize(0, 0, self.productsTable.contentSize), nil); 
    UIGraphicsBeginPDFPage(); 
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    [self.productsTable scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO]; 
    [self.productsTable.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    CGFloat screensInTable = self.productsTable.contentSize.height/self.productsTable.height; 

    for (int i = 1; i < screensInTable; i++) { 
     CGPoint contentOffset = CGPointMake(0, i * self.productsTable.height); 
     [self.productsTable setContentOffset:contentOffset animated:NO]; 
     [self.productsTable.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    } 

    UIGraphicsEndPDFContext(); 
3

Oto jak można rób to bez przewijania widoku tabeli. Po prostu zwiększ wysokość przewijania do contentSize. Jakość pliku PDF jest również lepsza, jeśli nie przejdziesz przez UIImage. To jest z mojego rozszerzenia UITableView w Swift. Kod jest skradziony tu i tam, więc komentarze nie zawsze są moje.

func toPDF(fileName: String) -> String { 
    // Don't include scroll indicators in file 
    self.showsVerticalScrollIndicator = false 

    // Creates a mutable data object for updating with binary data, like a byte array 
    let pdfData = NSMutableData() 

    // Change the frame size to include all data 
    let originalFrame = self.frame 
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.contentSize.width, self.contentSize.height) 

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

    // Draws rect to the view and thus this is captured by UIGraphicsBeginPDFContextToData 
    self.layer.renderInContext(pdfContext!) 

    // Remove PDF rendering context 
    UIGraphicsEndPDFContext() 

    // Retrieves the document directories from the iOS device 
    let documentDirectories: NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) 

    let documentDirectory = documentDirectories.objectAtIndex(0) 
    let documentDirectoryFilename = documentDirectory.stringByAppendingPathComponent(fileName); 

    // Instructs the mutable data object to write its context to a file on disk 
    pdfData.writeToFile(documentDirectoryFilename, atomically: true) 

    // Back to normal size 
    self.frame = originalFrame 

    // Put back the scroll indicator 
    self.showsVerticalScrollIndicator = true 

    return documentDirectoryFilename 
} 
+0

To wydaje się działać, ale kiedy to zrobię, klipy 1 i pół wiersza u góry i u dołu – vinbhai4u

0

myślę, że każdy zapomina, że ​​UITableView jest UIScrollView po wszystkim. Nie ma potrzeby obliczania komórek, wysokości itp. Możesz po prostu stworzyć swój kontekst za pomocą contentSize, ustawić tableView.frame.size = tableView.contentSize i wyrenderować w kontekście.

Zapoznaj tym przykładzie

 UIGraphicsBeginImageContext(tableView.contentSize) 
     let context = UIGraphicsGetCurrentContext() 

     let cachedOffset = CGPoint(x:tableView.contentOffset.x , y:tableView.contentOffset.y) 
     let cachedFrame = tableView.frame 

     tableView.contentOffset = .zero 
     tableView.frame = CGRect(x: 0, y: 0, width: tableView.contentSize.width, height: tableView.contentSize.height) 
     tableView.layer.render(in: context) 

     tableView.frame = cachedFrame 
     tableView.contentOffset = cachedOffset 

     if let image = UIGraphicsGetImageFromCurrentImageContext() { 
      let imageView = UIImageView(image: image) 
      self.createPDF(fromUIViews:myImage saveToDocumentsWithFileName:"PDF Name") 
     } 

     UIGraphicsEndImageContext()