【问题标题】:How to get a snapshot of UITableView in a PDF format如何以 PDF 格式获取 UITableView 的快照
【发布时间】:2013-04-08 18:40:01
【问题描述】:

我有一个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];
}

【问题讨论】:

    标签: ios uitableview pdf-generation


    【解决方案1】:

    没有屏幕外单元格,因为它们会在滚动出可见屏幕时立即被回收。您应该考虑使用 Core Text 创建 PDF 版本,而不是截取 UITableView。也许你可以适应这个example

    【讨论】:

    • 感谢您的信息..我有一小段代码可以帮助我进行快照过程,看看我的代码
    【解决方案2】:
    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"];
    

    我不知道,但这段代码对我来说就像一个魅力..

    【讨论】:

    • 不错!我不知道这个,你应该接受你自己的答案,
    • 您好,感谢您提供此代码。我一直在努力做到这一点。我不确定我做错了什么。我使用了这段代码,但在滚动 tableview 后它似乎不起作用。你能检查我的问题并提出你的想法吗 -stackoverflow.com/questions/17771112/… 真的很感激。
    • 谢谢,真的很有用,也别忘了UITableView继承自UIScrollView,所以可以做这样的事情:CGFloatscreensInTable = self.tableView.contentSize.height / self.tableView.frame.size。高度; for (int i = 1; i
    【解决方案3】:

    基于 Vin 的回答(也可用于 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();
    

    【讨论】:

      【解决方案4】:

      这是不滚动表格视图的方法。只需将滚动视图的高度增加到 contentSize。如果您不通过UIImage,PDF 的质量也会更好。这是来自我在 Swift 中的 UITableView 扩展。代码是从各处偷来的,所以 cmets 并不总是我的。

      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
      }
      

      【讨论】:

      • 这似乎有效,但是当我这样做时,它会在顶部和底部剪辑 1 行和半行
      【解决方案5】:

      我想每个人都忘记了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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-31
        • 1970-01-01
        相关资源
        最近更新 更多