3

我正在使用 Core Graphics 截取我的UIView的屏幕截图,然后将其放在该 View 的顶部(这样我以后可以对其进行动画处理):

// Get the screen shot
UIGraphicsBeginImageContextWithOptions(target.bounds.size, YES, [[UIScreen mainScreen] scale]);
[target.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIImageView * ss = [[UIImageView alloc] initWithImage:image];

// Add it to the View
[overlay addSubview:ss];
[target addSubview:overlay];

问题:我的 UIViewtarget上有一些不可见的项目(我都试过了alpha = 0hidden = YES。这些不可见的项目出现在屏幕截图中。

如何在不出现这些不可见项目的情况下截取屏幕截图?

更新: 我尝试使用Technical Q&A QA1703: Screen Capture in UIKit Applications 中的代码,这也存在同样的问题。

更新#2: 似乎应用了 CATransform3D 的视图会出现问题。在另一个具有 3D 子视图的父视图中,当截取此屏幕截图时,3D 效果将从视图中移除,并且它们看起来是平坦的 (2D)。

4

2 回答 2

1

为什么不从其超级视图中删除隐藏视图。然后它不会出现在屏幕截图上。

[hiddenView removeFromSuperview];

编辑:

如果您不知道隐藏了哪些子视图,可以检查一下。以下代码将从视图中删除所有隐藏的子视图并将它们添加回来。

NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(UIView *subView, NSDictionary *bindings) {
    return subView.hidden;
}];

NSArray *hiddenViews = [[myView subviews] filteredArrayUsingPredicate: predicate];

for (UIView *subView in hiddenViews) {
    [subView removeFromSuperview];
}

//take your screenshot here

for (UIView *subView in hiddenViews) {
    [myView addSubview:subView];
}

EDIT2:正如 Duncan C 指出的那样,这不适用于嵌套的 subviews。为此,您需要一个递归方法。

于 2012-09-05T19:41:35.827 回答
0

看起来问题不仅在于它们被隐藏了,还在于应用了 CATransform3D。

Stack Overflow 问题“renderInContext:”和 CATransform3D有更多信息,但要点是:

QCCompositionLayer、CAOpenGLLayer 和 QTMovieLayer 图层不会被渲染。此外,不会渲染使用 3D 变换的图层,也不会渲染指定 backgroundFilters、filters、compositingFilter 或掩码值的图层。

(来自CALayer 文档)。

如果您的应用没有进入应用商店,您可以使用未记录的UIGetScreenImageAPI:

// Define at top of implementation file
CGImageRef UIGetScreenImage(void);

...

- (void)buttonPressed:(UIButton *)button
{
  // Capture screen here...
  CGImageRef screen = UIGetScreenImage();
  UIImage* image = [UIImage imageWithCGImage:screen];
  CGImageRelease(screen);

  // Save the captured image to photo album
  UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}

(来自约翰·穆肖

但是,使用此 API 会使您的应用无法获得批准。

我一直找不到任何其他解决方法。

于 2012-09-12T13:17:32.370 回答