私はこのような折りたたみメニューアニメーションを作成しようとしています:http://vimeo.com/41495357
この時点で、画面上で指をドラッグするとアニメーションは機能しますが、メニューを開いた状態から閉じた状態、または閉じた状態から直接開いた状態にアニメーション化しようとすると、スライドして離れたメインビューがビューの右側に整列しません。それが展開しています。アニメーションが終了すると整列されますが、途中では整列されません。また、展開中のビューのエッジは、アニメーション中にビューの境界の外側に消えるように見えます。
レイヤーの実際の展開はlayoutSublayersで行われるため、レイヤーの幅が変更されると、そのサブレイヤーでの変換が計算されます。このプロジェクトで変換を計算するための数学を見つけました:https ://github.com/MassiveHealth/Opaque
// Configure the layer bounds and midpoints
CGRect halfRect = CGRectMake(0, 0, self.fullWidth / 2, self.bounds.size.height);
self.rightImageLayer.bounds = halfRect;
self.leftImageLayer.bounds = halfRect;
CGPoint midPoint = CGPointMake(0.5 * self.bounds.size.width, 0.5 * self.bounds.size.height);
self.rightImageLayer.position = midPoint;
self.leftImageLayer.position = midPoint;
// Calculate transforms
CGFloat l = 0.5 * self.fullWidth;
CGFloat y = 0.5 * self.bounds.size.width;
CGFloat theta = acosf(y/l);
CGFloat z = l * sinf(theta);
CGFloat topAngle = theta * -1;
CGFloat bottomAngle = theta;
CATransform3D transform = CATransform3DMakeTranslation(0.0, 0.0, -z);
self.rightImageLayer.transform = CATransform3DRotate(transform, topAngle, 0.0, 1.0, 0.0);
self.leftImageLayer.transform = CATransform3DRotate(transform, bottomAngle, 0.0, 1.0, 0.0);
これは、展開アニメーションの開始を担当するコードです。(現在、メニューは画面の幅全体に展開されます)
self.foldingLayer.frame = self.view.bounds;
self.slidingLayer.frame = CGRectMake(self.view.frame.size.width, 0, self.slidingLayer.frame.size.width, self.slidingLayer.frame.size.height);
なぜこれらのアニメーションが整列しないのですか?おそらく数学は間違っていますか?https://github.com/honcheng/PaperFold-for-iOSやhttps://github.com/xyfeng/XYOrigamiなどのプロジェクトのサンプルコードを見ましたが、わかりません。
アップデート
Tillの回答に基づいて、スライディングレイヤー用にこのキーフレームアニメーションを作成しました。アニメーションがまだ整列していないので、キーフレームの計算が間違っている必要がありますか?
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.x"];
NSUInteger steps = 100;
CGFloat totalFoldViewWidth = self.view.bounds.size.width;
NSMutableArray *values = [NSMutableArray arrayWithCapacity:steps];
for(NSUInteger i = 0; i < steps; i++) {
CGFloat fraction = (CGFloat)i / steps;
CGFloat foldViewWidth = fraction * totalFoldViewWidth;
CGFloat l = 0.5 * totalFoldViewWidth;
CGFloat y = 0.5 * foldViewWidth;
CGFloat angle = acosf(y/l);
CGFloat projectionWidth = cosf(angle) * totalFoldViewWidth;
[values addObject:[NSNumber numberWithFloat:projectionWidth]];
}
animation.calculationMode = kCAAnimationLinear;
[animation setValues:values];
[animation setDuration:3.0];
[self.slidingLayer addAnimation:animation forKey:@"slideAnimation"];