【问题标题】:Screenshot from a UITableViewUITableView 的屏幕截图
【发布时间】:2011-06-19 12:37:14
【问题描述】:

我知道关于这个主题有很多问题,但我真的阅读了所有这些问题,但是 没有找到答案。

我想从当前的表格视图中截屏。我这样做:

-(UIImage *)imageFromCurrentView
{
    UIGraphicsBeginImageContextWithOptions(self.tableView.bounds.size, YES, 1);
    [self.tableView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

一切正常,但是当我在表格视图中向下滚动并制作屏幕截图时, 图像的一半是黑色的。我不知道如何从实际中制作屏幕截图 表格视图区域。

【问题讨论】:

    标签: iphone objective-c ios uitableview ios4


    【解决方案1】:

    这将为您提供 TableView 的当前可见区域。

    如果你想渲染整个 tableview,首先你需要知道这可能不是一个好主意,因为内存的原因超过了几十行,等等。最大图像尺寸为 2048x2048,因此您的 tableView 不能高于此尺寸。

    UIView *viewToRender = self.tableView;
    CGPoint contentOffset = self.tableView.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();
    
    UIGraphicsEndImageContext();
    

    【讨论】:

    • 这应该被标记为正确答案,至少它为我修复了它。 CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0, -contentOffset.y);
    • 这回答了我的问题,即如何截取滚动的 UIScrollView(UITableView 或其他)的屏幕截图。在截取已滚动的滚动视图的屏幕截图时,我得到了与滚动偏移量大小相同的黑条。所以,谢谢,谢谢,谢谢。
    【解决方案2】:

    看看这个library我就是这样做的,它有非常有用的方法,比如:

    1. 截取您的 UITableView 的完整屏幕截图(所有单元格都呈现在单个 UIImage 上)
    2. 只为一个给定 indexPath 的单元格截屏
    3. 只截取 UITableView 的页眉、页脚或行的屏幕截图

    还有更多...

    您可以通过 Cocoapods 或通过拖动源文件手动将其添加到您的项目中。

    用法就是这么简单:

    UIImage * tableViewScreenshot = [self.tableView screenshot];
    

    我希望你和我一样觉得这个库很有帮助。

    【讨论】:

    • 迄今为止我见过的最令人兴奋的图书馆 :) 非常感谢!
    【解决方案3】:

    以下代码在我的应用程序中完美运行,您可以使用此代码捕获 tableview 或任何其他具有水平滚动的滚动视图的屏幕截图

    CGPoint 偏移 = [_tableView contentOffset]; _tableView.contentOffset = CGPointMake(0.0, 0.0); CGRect visibleRect = _tableView.bounds; UIGraphicsBeginImageContextWithOptions(_tableView.contentSize, _tableView.opaque, 0.0); [_tableView.layer renderInContext:UIGraphicsGetCurrentContext()]; while (_tipsTableView.contentSize.height>= (visibleRect.origin.y+visibleRect.size.height)) { visibleRect.origin.y += visibleRect.size.height; [_tableView scrollRectToVisible:visibleRect 动画:NO]; [_tableView.layer renderInContext:UIGraphicsGetCurrentContext()]; } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); _tableView.contentOffset = 偏移量;

    【讨论】:

      【解决方案4】:

      因为 UITableViewCell 是可重用的,当滚动表格视图时,视口之外的单元格将被排入队列以供重用并从表格视图中删除。所以尽量保持单元格只能在其索引路径上重复使用:

      - (UITableViewCell *)tableView:(UITableView *)tableView
               cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {
        NSString *cellIdentifier = [NSString stringWithFormat:@"Cell_%d_%d", indexPath.section, indexPath.row]; 
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (cell == nil) {
          cell = [[[UITableViewCell alloc] initWithReuseIdentifier:cellIdentifier] autorelease];
        }
        ...
        return cell;
      }
      

      尚未测试,试一试。是的,这会消耗更多内存,仅用于屏幕截图。

      编辑:如果您关心内存使用情况,可能您可以截取当前视口的屏幕截图,然后以编程方式上下滚动以截取其他部分的屏幕截图,最后合并所有屏幕截图。

      【讨论】:

      • 感谢您的回答。我不确定您的意思是“仅以屏幕截图为目的”。现在我有一个制作屏幕截图的按钮。当我按下屏幕截图按钮而不消耗更多内存时,我必须用这段代码做什么?
      • 在正常情况下,只能包含多于或等于视口一窝的单元格数量,它们在滚动表格视图时可重复使用,因此即使包含大量也可以顺利运行项目。在我这里的路上,单元格的数量与表格视图的所有行数相同,所以如果你的表格视图有大量的项目,它会比正常的方式消耗大量的内存。所以要小心。如果你首先考虑内存使用,不要使用这种方法,虽然它可以工作。
      • 我遇到了完全相同的问题,但这并没有为我解决问题。 @Missaq 这是否为您解决了问题?
      • 嗨,我知道这有点过时了,但是对于其他搜索这个的人,你可以看看这个库:github.com/davidman/DHSmartScreenshot
      【解决方案5】:
      - (UIImage *) imageWithView:(UIView *)cellTobeCaptured isImage:(BOOL)isImage
      {
      
      //If UITableViewCell contains UIImageView
      
          if(isImage){
           UIGraphicsBeginImageContextWithOptions(cellTobeCaptured.bounds.size, NO, [UIScreen mainScreen].scale);
           [cellTobeCaptured drawViewHierarchyInRect:CGRectMake(0, 0, cellTobeCaptured.bounds.size.width, cellTobeCaptured.bounds.size.height) afterScreenUpdates:NO];
           UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
           UIGraphicsEndImageContext();
           return image;
          }
      else{
        UIGraphicsBeginImageContextWithOptions(cellTobeCaptured.bounds.size, cellTobeCaptured.opaque, 0.0);
        [cellTobeCaptured.layer renderInContext:UIGraphicsGetCurrentContext()];
         UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
         UIGraphicsEndImageContext();
         return img;
         }
      }
      

      => 调用方法为

       UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:arrIndex inSection:0]];
       self->screenShotImage = [self imageWithView:cell isImage:YES];
      

      【讨论】:

        【解决方案6】:

        我在使用 UITableView 构建的自定义日历中更改月份时尝试复制 Apple 日历滚动时遇到了类似的问题。在调用scrollToRowAtIndexPath:之后,确保animated:是YES以便调用scrollViewDidEndScrollingAnimation:,在scrollViewDidEndScrollingAnimation:中我在renderInContext:之前的tableView上调用了reloadData:。然后将完整的 tableview 渲染到图像。从长远来看,我最终没有使用它,因此不确定它作为永久解决方案的可靠性,但当我尝试它时效果很好。

        【讨论】:

          【解决方案7】:

          对于 Swift 5,您可以使用此代码

              let viewToRender = tableView;
              let contentOffset = tableView.contentOffset
          
              UIGraphicsBeginImageContext(viewToRender.bounds.size)
          
              if let ctx = UIGraphicsGetCurrentContext() {
                 ctx.translateBy(x: 0, y: -contentOffset.y)
          
                 viewToRender.layer.render(in: ctx)
          
                 let image = UIGraphicsGetImageFromCurrentImageContext();
          
              }
              UIGraphicsEndImageContext();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-07-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-20
            • 1970-01-01
            • 2012-03-10
            相关资源
            最近更新 更多