从UITableView创建具有顶部和底部偏移的UIImage

时间:2016-06-09 18:29:10

标签: ios objective-c uitableview uiimage

我正在尝试创建一个实用程序函数,它允许我从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

有关如何解决此问题的任何建议?

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

好的,我有相当合理的解决方案。我这样做的一个主要障碍是我没有意识到照片居中在预览中裁剪图像。你必须实际缩小才能看到完整的图像......这让我们浪费了太多时间。

来自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框架以匹配内容大小。可以考虑中间的代码块,但我将其留在两个解决方案中以便于复制粘贴。