Core Graphics截图没有隐藏的项目

时间:2012-09-05 18:21:50

标签: objective-c ios uiview core-animation core-graphics

我正在使用Core Graphics截取我的 UIView 的屏幕截图,然后将其置于该视图的顶部(以便稍后我可以为其设置动画):

// 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];

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

如何在没有出现这些隐形物品的情况下拍摄截图?

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

更新#2:对于已应用CATransform3D的视图,似乎会出现此问题。在具有3D子视图的另一个父视图中,当拍摄此屏幕截图时,3D效果将从视图中删除,并且它们显示为平面(2D)。

2 个答案:

答案 0 :(得分: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指出的那样,这对嵌套子视图不起作用。你需要一个递归方法。

答案 1 :(得分:0)

看起来问题不仅仅是它们被隐藏了,而是应用了CATransform3D。

Stack Overflow问题"renderInContext:" and CATransform3D有更多信息,但要点是:

  

未呈现QCCompositionLayer,CAOpenGLLayer和QTMovieLayer图层。此外,不会渲染使用3D变换的图层,也不会渲染指定backgroundFilters,filters,compositingFilter或蒙版值的图层。

(来自the CALayer docs)。

如果您的应用未访问应用商店,则可以使用未记录的UIGetScreenImage API:

// 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);
}

(来自John Muchow

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

我无法找到任何其他解决方法。