11

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

简单地禁用动画并突然交换视图是可以容忍的,但远低于我正在构建到应用程序其余部分的润色。我更愿意这样做:

当 shouldAutorotateToInterfaceOrientation: 被调用时,我想抓取一个不透明的视图快照,如果你愿意的话,一个屏幕截图,在旋转之前的用户视图。然后在旋转完成并且系统应用了视图变换等之后,我可以显示我保存的快照视图,并将我选择的动画转换为我的新视图。完成后,我可以释放我的快照并继续前进。

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

我能想到的唯一其他选择是在我的默认方向以外的所有方向上返回 NO,然后通过应用我自己的动画和变换来做出反应。但是,我更喜欢使用系统来执行此操作,因为我觉得自己可能会在手动旋转视图等中导致“未定义”键盘行为。

想法?

4

4 回答 4

21
- (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;
}

在这里找到这个:

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

于 2009-11-22T09:42:12.513 回答
12

这段代码对我有用

- (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;
}
于 2011-08-16T17:59:09.280 回答
4

在 Mac 上,这很容易……你只需要-bitmapImageRepForCachingDisplayInRect:,但当然 iPhone 没有这样的东西。

我想我会通过设置图形上下文并调用[window drawRect:...]它来捕获屏幕的当前图像来解决这个问题。这有点不合规格,因为你真的不应该打电话给-drawRect:自己。我会有点担心这样做的副作用,但它可能没问题。如果它是您控制的全屏视图,您当然可以将绘图代码提升出来,-drawRect:这样您就不会直接调用它。

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

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

编辑:感谢 Rob Terrell 和他聪明的UIApplication+TVOut.m,我被介绍给返回 CGImageRef 的私有方法 UIGetScreenImage()。如果您愿意使用私有方法,那对您来说是一个不错的选择。鉴于它的名称和功能,它在我看来相当稳定,似乎不太可能违反 Apple 的意图。我还碰到了一个关于Air Source的非常好的讨论。通读几个链接的评论。

于 2009-05-18T18:31:29.190 回答
1

我可以保证你 [window drawRect:] 不会工作。大多数视图没有实现 drawRect: 并且它肯定不像在 mac 上那样递归。

drawInContext: 也非常相似,因为它从根本上要求图层绘制自己,而不是递归地绘制它的子图层。“默认实现什么都不做。” 说明了一切。

我通过执行以下操作在应用商店中为 Clif Bar Save Our Snow 应用程序实现此功能:

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

是的,相当大的痛苦。但是,是的,它运行得很好,并且被 Apple 通过了 :)。

于 2009-05-28T02:00:46.970 回答