如何捕捉当前视图截图并在代码中重用? (iPhone SDK)

我正试图从一个UIView转换到另一个,当用户旋转设备。 这本身并不困难。 但是,由于我在旋转后显示完全不同的内容,UIKit提供的默认animation(旋转当前显示的视图)在概念上是不恰当的。

简单地禁用animation和突然交换视图是可以接受的,但远低于我正在构build到应用程序的其余部分的波兰。 我想要做的是这样的:

当shouldAutorotateToInterfaceOrientation:被调用时,我想在旋转之前获取用户视图的不透明视图快照,如果您愿意的话, 然后在旋转完成后,系统应用视图转换等,我可以显示我保存的快照视图,并将我select的过渡animation到我的新视图。 完成后,我可以释放我的快照,继续前进。

有没有办法做到这一点不昂贵?

我能想到的唯一的另一个select是在除了默认方向之外的所有方向上返回NO,然后通过应用我自己的animation和变换来作出反应。 然而,我宁愿使用系统来做到这一点,因为我觉得这可能会导致手动旋转的视图中的“未定义的”键盘行为。

思考?

我可以保证你[窗口drawRect:]将无法正常工作。 大多数视图不执行drawRect:它肯定不像Mac上的recursion。

drawInContext:也基本上要求图层自己绘制,而不是recursion地绘制子图层。 “默认实现什么都不做”。 这一切说。

我通过执行以下操作为Clif Bar在App Store中保存我们的Snow应用程序:

  • recursion地走分层结构,从每一层获取内容。 如果它闻起来像一个图像,使用CGContext方法将其绘制到您的上下文中。
  • 在步行时,请确保在recursion调用时应用每个图层的转换/位置

是的,屁股上有一个相当大的痛苦。 但是,是的,它工作得很好,通过苹果:)。

- (UIImage *)captureView:(UIView *)view { CGRect screenRect = [[UIScreen mainScreen] bounds]; UIGraphicsBeginImageContext(screenRect.size); CGContextRef ctx = UIGraphicsGetCurrentContext(); [[UIColor blackColor] set]; CGContextFillRect(ctx, screenRect); [view.layer renderInContext:ctx]; UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; } 

在这里find这个:

http://discussions.apple.com/thread.jspa?messageID=8358740

此代码为我工作

 - (UIImage *)captureScreenInRect:(CGRect)captureFrame { CALayer *layer; layer = self.view.layer; UIGraphicsBeginImageContext(self.view.bounds.size); CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame); [layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return screenImage; } 

在Mac上这是如此简单…你只需要-bitmapImageRepForCachingDisplayInRect:但当然iPhone没有这样的事情。

我想我会设置一个graphics上下文,并调用[window drawRect:...]来捕获当前的屏幕图像。 这是有点超出规格,因为你不是真的应该去调用-drawRect:你自己。 我这样做会有点紧张的副作用,但可能会很好。 如果是全屏视图,则可以将绘图代码从-drawRect:提取出来,这样就不会直接调用它。

类似的方法是使用当前的-presentationLayer CALayer -drawInContext: -presentationLayer 因为通过你自己的上下文是合法的,所以这可能稍微“在规范中”。 但是我不知道你是否真的能够正确地获得所有的子视图。 可能取决于你的UIWindow的性质。

无论如何,很好的问题。 也许有人有一个更聪明的解决scheme,但这是我的方式攻击它。

编辑:感谢Rob Terrell,和他聪明的UIApplication + TVOut.m ,我被介绍到私有方法UIGetScreenImage(),它返回一个CGImageRef。 如果你愿意去私人的方法,这是一个很好的select。 鉴于其名称和function,它看起来相当稳定,似乎不太可能违反苹果的意图。 我也碰到了一个关于Air Source的非常好的讨论。 通读几个链接的评论。