13

我很清楚,除了渲染整个视图和裁剪之外,没有很好的方法可以将 UIView 的一小部分渲染到图像上。(在 iPad 3 之类的设备上非常昂贵,生成的图像很大)。有关 renderInContext 方法的描述,请参见此处(没有其他选择)。

我要渲染的视图部分无法预先确定,这意味着我无法将小部分的视图层次结构设置为它自己的 UIView(因此是 CALayer)。

我的点子...

我有一个想法,但如果我要成功,我需要一些方向。如果我在 UIView(或 CALayer)上创建一个类别,该类别添加一个方法如下:

[UIView renderSubframe:(CGFrame)frame];

如何?好吧,我在想,如果创建了一个子框架大小的虚拟视图,那么视图可以暂时转移到这个上面。然后虚拟视图的层可以调用renderInContext:,从而获得一种高效且快速的方式来获取视图。

所以...

我真的没有跟上 CALayer/Quartz 核心的速度……这有机会工作吗?如果没有,还有什么方法可以达到同样的效果——我可以达到相同结果的最有效方法是什么(或者其他人已经面临这个问题并提出不同的解决方案)?

4

2 回答 2

28

这是我最终写的类别。多亏了方便的 CGAffineTransform,没有我最初想的那么难。

#import "UIView+RenderSubframe.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIView (RenderSubframe)

- (UIImage *) renderWithBounds:(CGRect)frame {

    CGSize imageSize = frame.size;

    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0);
    CGContextRef c = UIGraphicsGetCurrentContext();

    CGContextConcatCTM(c, CGAffineTransformMakeTranslation(-frame.origin.x, -frame.origin.y));
    [self.layer renderInContext:c];

    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return screenshot;

}

@end
于 2013-01-06T12:34:49.653 回答
1

您可以通过几种不同的方式执行此操作:

  1. CGContextClipToRect在调用 renderInContext 之前为您的上下文指定 a ;

  2. 采用:

setNeedsDisplayInRect:

将指定矩形内的区域标记为需要更新。

     - (void)setNeedsDisplayInRect:(CGRect)theRect

这将使渲染仅在指定的矩形中发生。我不确定这是否符合您的要求。

我认为第一个选项应该无缝工作。

于 2013-01-05T11:16:13.537 回答