layer.transform を新しいトランスフォームに設定すると、レイヤーが終了位置で点滅し、現在の位置から終了位置までアニメーション化することがあります。
これが関連しているかどうかはわかりませんが、同時にレイヤーのスーパーレイヤーに sublayerTransform を設定しています。
なぜこれが起こっているのか、私にはまったくわかりません。どんな考えでもいただければ幸いです。
ありがとう。
アップデート
サブレイヤー変換を削除すると、この動作は発生しません。
これが私の初期設定です。
次のように、sublayerTransform で暗黙的なアクションを回避します。
self.actions = [NSDictionary dictionaryWithObject:[NSNull null] forKey:@"sublayerTransform"];
このメソッドは、個々のレイヤーを変換します
- (void)setSelectedCover:(int)cover{
selectedCover = cover;
CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]];
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:0.3f]
forKey:kCATransactionAnimationDuration];
coverLayer.transform = flippedUpTransform;
[CATransaction commit];
}
このメソッドは、スクロールのような効果を作成します (より便利なスクロール方法があることはわかっていますが、これが今のところ私のニーズに最適な実装です)。このメソッドは、指が画面上を移動するたびに呼び出されます。
- (void)setScrollOffset:(float)offset absolute:(BOOL)absolute animated:(BOOL)animated{
CATransform3D aSublayerTransform = self.sublayerTransform;
scrollOffset = aSublayerTransform.m41;
if (absolute) {
scrollOffset = offset;
}else {
scrollOffset += offset;
}
[self setValue:[NSNumber numberWithInt:scrollOffset] forKeyPath:@"sublayerTransform.translation.x"];
}
また。これは第 2 世代のデバイス (第 3 世代ではなく) でのみ再現できるため、一部はデバイスのパフォーマンスの問題であると思われますが、それでも回避策が必要です。
次のように CABasicAnimation (明示的なアニメーション) を使用することを検討しました。
- (void)setSelectedCover:(int)cover{
selectedCover = cover;
CoverLayer *coverLayer = [onScreenCovers objectForKey:[NSNumber numberWithInt:cover]];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.toValue = [NSValue valueWithCATransform3D:flippedUpTransform];
animation.duration = 0.3f;
[coverLayer addAnimation:animation forKey:@"transform"];
}
これは実際には非常にうまく機能し、ちらつきはありません! 現在の唯一の問題は、それを維持することです。
だから私はアニメーションにこれを追加しました:
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
これにより、実際にはアニメーションの最後にとどまりましたが、同様のタスクに取り組んでいる人にとって、これらの2行を追加するとプレゼンテーションレイヤーが固執するだけで、モデルレイヤーに永続化されないことを知っておくことが重要だと思います. 私の場合、layer.transform = newtransform と言って、再度変換したい場合は手元のレイヤーに追加の変換があり、モデルは変更されませんでした。私のレイヤーは、明示的なアニメーションを実行する前の元の変換に戻ります。
そのため、変換を永続化するという問題をかなりうまく解決できたと思いました。追加した:
animation.delegate = coverLayer.delegate;
私の場合、アニメーション化される各レイヤーには独自のデリゲートが必要です。物事が非常に速く動くため、複数のレイヤーを同時にアニメーション化できるからです。そのため、各レイヤーがそれ自体を担当する必要があります。
これは私がデリゲートに実装したものです。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
if (flag) {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue
forKey:kCATransactionDisableActions];
cover.transform = flippedUpTransform;
[CATransaction commit];
[cover performSelector:@selector(removeAllAnimations) withObject:nil afterDelay:0.2];
}
}
アニメーションが正常に完了したら、完成した変換をモデル自体に適用します
他の変換が設定されている場合、最後に追加したアニメーションが実行されるため、明示的なアニメーションを削除した直後。
これは機能します。
アニメーションが完了していない場合は、何もしません。モーダル レイヤーを更新する必要はありません。中断したアニメーションが、中断したところから再開し、プレゼンテーションが永続化されるようにする必要があるためです。
問題は、遅延呼び出しが常に正しく行われることに依存していることです。そうではありません、それはそれを十分にまとめますが、時には物事が少しずれて見えることがあります. 最後に、これ以上修正できない場合は、この解決策を受け入れます。ただ滑らかじゃない…