如何在完成块中正确使用renderInContext?

时间:2012-06-24 15:45:58

标签: ios uikit core-animation

我的视图/图层层次结构如下所示:

CustomUIView  [A]
  |
  +--- UIImageView [B]

首次显示UI时,视图[B]显示默认图像(游戏板)。

为了对用户事件做出反应,我创建了一些CALayer个对象并将它们添加为子层来查看[A]的后备层。然后我使用它们来渲染动画,光学地改变游戏板的部分,因为它们分层地位于图像视图的顶部。这很好用。

动画完成后,我想截取生成的图层状态的屏幕截图,将其设置为[B]的新图像,然后在游戏中的下一步移动之前丢弃临时子图层。

我的代码如下所示:

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    UIImage *snapshot = [self.view snapshot];
    self.snapshotVIew.image = snapshot;
    for (CALayer *tileLayer in tempLayers)
    {
        [tileLayer removeFromSuperlayer];
    }
}];

CAAnimationGroup *animGroup = [CAAnimationGroup animation];
animGroup.animations =@[contentAnimation, zoom];
animGroup.duration = 0.5f;
animGroup.removedOnCompletion = NO;
animGroup.fillMode = kCAFillModeForwards;
for (CALayer* tileLayer in tempLayers)
{
    [tileLayer addAnimation:animGroup forKey:nil];
}
[CATransaction commit];

我的自定义视图的快照方法非常标准:

- (UIImage*) snapshot {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, [[UIScreen mainScreen] scale]);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage* img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

问题似乎是renderInContext的文档说:

  

将接收器及其子层渲染到指定的上下文中。   此方法直接从图层树渲染,忽略添加到渲染树的任何动画

由于最后一个突出显示的句子,一旦删除了图层,一切都像以前一样。显然,当完成块运行时,图层树似乎没有使用完成的动画状态进行更新,因此我的屏幕截图不考虑这一点。

我将如何做到这一点?

1 个答案:

答案 0 :(得分:2)

尝试渲染图层的presentationLayer:

[self.layer.presentationLayer renderInContext:UIGraphicsGetCurrentContext()];

或者,不是使用removedOnCompletion = NO,而是在添加动画后将图层的属性设置为最终状态。然后,当动画完成时,图层将反映更改的外观,您可以渲染普通图层。