【问题标题】:Create UIImage from UITableView with top and bottom offset从具有顶部和底部偏移的 UITableView 创建 UIImage
【发布时间】:2016-10-10 13:23:49
【问题描述】:

我正在尝试创建一个实用程序函数,该函数允许我从 UITableView 创建 UIImage 以供用户共享。

我遇到的问题是我在表格的标题视图(如果用户不是高级用户,它是一个广告)和表格的最后一行(内容的实用程序按钮栏)中都有无关的内容.

更新 - 为此,我有以下功能:

+ (UIImage *)imageFromTable:(UITableView *)tableView
                  topOffset:(CGFloat)topOffset
               bottomOffset:(CGFloat)bottomOffset {
    UIImage *image = nil;

    // store the old frame so we can reset the table after the image is created
    CGRect oldFrame = tableView.frame;

    // set the table frame equal to content size so content is not cut off by screen dimens
    [tableView setFrame:CGRectMake(0, 0, tableView.contentSize.width, tableView.contentSize.height)];

    // create a rendering frame to use for cropping our image
    CGRect renderFrame = CGRectZero;
    renderFrame.size.width = tableView.contentSize.width;
    renderFrame.size.height = tableView.contentSize.height;
    renderFrame.size.height -= bottomOffset;

    // generate the image from the custome tableview frame
    UIGraphicsBeginImageContextWithOptions(tableView.contentSize, tableView.opaque, 0.0);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, 0, -topOffset); // move up by top offset to crop top content
    CGContextClipToRect(ctx, renderFrame); // clip to render frame to crop bottom content
    [tableView.layer renderInContext:ctx];
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // TODO: remove black excess at bottom of image

    // reset the table with the old frame and return the image
    [tableView setFrame:oldFrame];
    return image;
}

很遗憾,这种方法只能成功处理底部内容的移除。

如果我也这样做renderFrame.size.height -= topOffset;,它将从表格​​视图的底部而不是顶部移除更多的高度。

更新 - 我现在有了following image,这几乎是我所需要的,但在图像底部留下了一个黑条,我似乎无法正确删除它。它的高度等于topOffset+bottomOffset

关于我应该如何解决这个问题的任何建议?

【问题讨论】:

  • 我的建议是复制这个 tableView 实例并删除你不想要的额外内容,然后渲染它。
  • 老实说,我真的希望尽可能避免这种情况
  • 我使用了您的示例和CGContextClipToRect 来更接近解决方案,但现在我的图像底部留下了一个大的黑色部分。你有什么建议吗?

标签: ios objective-c uitableview uiimage


【解决方案1】:

好的,所以我有相当合理的解决方案。我在执行此操作时遇到的主要障碍之一是我没有意识到照片 在预览中居中裁剪图像。您实际上必须缩小才能看到完整的图像......这让我们浪费了太多时间。

来自 UITableView 的 UIImage 带有顶部和底部偏移

+ (UIImage *)imageFromTable:(UITableView *)tableView
                  topOffset:(CGFloat)topOffset
               bottomOffset:(CGFloat)bottomOffset {
    UIImage *image = nil;

    // store the old frame so we can reset the table after the image is created
    CGRect oldFrame = tableView.frame;

    // set the table frame equal to content size so content is not cut off by screen dimens
    [tableView setFrame:CGRectMake(0, 0, tableView.contentSize.width, tableView.contentSize.height)];

    // create a cropping frame to use for cropping our image
    CGRect cropFrame = CGRectZero;
    cropFrame.size.width = tableView.contentSize.width;
    cropFrame.size.height = tableView.contentSize.height;
    cropFrame.size.height -= topOffset;
    cropFrame.size.height -= bottomOffset;

    // create image context with tableView content size
    // 0.0 uses [UIMain screen].scale
    UIGraphicsBeginImageContextWithOptions(cropFrame.size, tableView.opaque, 0.0);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, 0, -topOffset); // move up by top offset to crop top content
    [tableView.layer renderInContext:ctx]; // render our layer
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // reset the table with the old frame and return the image
    [tableView setFrame:oldFrame];
    return image;
}

我还需要类似的功能来从具有类似顶部和底部偏移量的 UIView 创建 UIImage,所以我在此处添加了该功能,以备不时之需。

来自 UIView 的 UIImage 带有顶部和底部偏移

+ (UIImage *)imageFromView:(UIView *)view
                 topOffset:(CGFloat)topOffset
              bottomOffset:(CGFloat)bottomOffset {
    UIImage *image = nil;

    // create a rendering frame to use for cropping our image
    CGRect cropFrame = CGRectZero;
    cropFrame.size.width = view.frame.size.width;
    cropFrame.size.height = view.frame.size.height;
    cropFrame.size.height -= topOffset;
    cropFrame.size.height -= bottomOffset;

    // create image context with tableView content size
    // 0.0 uses [UIMain screen].scale
    UIGraphicsBeginImageContextWithOptions(cropFrame.size, view.opaque, 0.0);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, 0, -topOffset); // move up by top offset to crop top content
    [view.layer renderInContext:ctx]; // render our layer
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

您会注意到这种方法要简单得多,因为您不必在截取“屏幕截图”之前修改 tableview 框架以匹配内容大小。中心代码块可以被分解出来,但我把它留在了两个解决方案中以便于复制粘贴。

【讨论】:

    【解决方案2】:

    我认为您需要更改框架的origin 以删除顶部的内容renderFrame.origin.y += topOffsetrenderFrame.size.height -= (topOffset + bottomOffset)

    【讨论】:

    • 很遗憾,这不起作用,因为UIGraphicsBeginImageContextWithOptions 只考虑了渲染帧的大小而不是原点
    猜你喜欢
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多