Ios 如何获取PDF格式的UITableView快照

Ios 如何获取PDF格式的UITableView快照,ios,uitableview,pdf-generation,Ios,Uitableview,Pdf Generation,我有一个UITableView,其中填充了一些数据,但因为它包含的数据比屏幕的可视区域多,所以我只能获取它的快照,我想知道是否有其他方法可以以pdf格式获取整个tableview快照。这是我尝试过的,谢谢 - (IBAction)clickMe:(id)sender { UIView *viewToRender = self.myTableView; CGPoint contentOffset = self.myTableView.contentOffset; UIGr

我有一个
UITableView
,其中填充了一些数据,但因为它包含的数据比屏幕的可视区域多,所以我只能获取它的快照,我想知道是否有其他方法可以以pdf格式获取整个tableview快照。这是我尝试过的,谢谢

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

没有屏幕外的单元格,因为它们一滚出可见屏幕就被回收。你应该考虑使用核心文本创建PDF版本,而不是截屏UITababVIEW。也许您可以对此进行调整。

UIGraphicsBeginImageContext(self.myTableView.contentSize);
[self.myTableView ScrollToRowatineXpath:[NSIndexPath indexPathForRow:0第0节:0]atScrollPosition:UITableViewScrollPositionTop动画:否];
[self.myTableView.layer RenderContext:UIGraphicsGetCurrentContext()];
int rows=[self.myTableView numberOfRowsInSection:0];
int numberofRowsInView=4;
对于(int i=0;i
我不知道,但这段代码对我来说很有魅力。

基于Vin的回答(也可用于拍摄UIScrollView):

UIGraphicsBeginPDFContextToData(pdfData,CGRectMakeWithSize(0,0,self.productsTable.contentSize),nil);
UIGraphicsBeginPDFPage();
[self.view.layer renderContext:UIGraphicsGetCurrentContext()];
[self.productsTable scrollRectToVisible:CGRectMake(0,0,1,1)动画:否];
[self.productsTable.layer RenderContext:UIGraphicsGetCurrentContext()];
CGFloat screensInTable=self.productsTable.contentSize.height/self.productsTable.height;
对于(int i=1;i
以下是无需滚动tableview即可完成此操作的方法。只需将scrollview的高度增加到contentSize即可。如果不通过
UIImage
,PDF的质量也会更好。这是来自Swift中我的
UITableView
扩展名。代码到处都是偷来的,所以注释并不总是我的

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
}

我想大家都忘了,
UITableView
毕竟是一个
UIScrollView
。无需计算单元格、高度等。只需使用
contentSize
创建上下文,设置
tableView.frame.size=tableView.contentSize
并在上下文中渲染即可

请看这个例子

        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()

谢谢你提供的信息。我得到了一小段帮助我完成快照过程的代码,看看我的代码!我不知道这个,你应该接受你自己的答案,嗨,谢谢你的代码。我一直在努力做到这一点。我不确定我做错了什么。我使用了这段代码,但在我滚动tableview之后,它似乎不起作用。请检查我的问题并给出您的想法好吗?非常感谢。谢谢,非常有用,也不要忘记UITableView继承自UIScrollView,因此可以执行以下操作:CGFloat screensInTable=self.tableView.contentSize.height/self.tableView.frame.size.height;对于(int i=1;ifunc 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 }
        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()