ビュー/レイヤー階層は次のようになります。
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
のドキュメントに次のように記載されているようです。
レシーバーとそのサブレイヤーを指定されたコンテキストにレンダリングします。このメソッドは、レンダー ツリーに追加されたアニメーションを無視して、レイヤー ツリーから直接レンダリングします。
最後の強調表示された文のために、レイヤーが削除されると、すべてが以前と同じように見えます。どうやら、完了ブロックが実行されると、レイヤー ツリーが完成したアニメーション状態で更新されていないように見えるため、私のスクリーンショットではそれが考慮されていません。
どうすればこれを行うことができますか?