我正在尝试创建一个类似于http://vimeo.com/41495357的折叠菜单动画。目前,在屏幕上拖动手指时,动画可以正常工作。但是,当我尝试直接从打开到关闭或者从关闭到打开动画菜单时,向右滑动的主视图与展开视图的右侧不对齐。它们在动画结束时对齐,但在动画过程中不对齐。此外,在动画期间,展开视图的边缘似乎会消失在视图的边界之外。
实际的展开层是在layoutSublayers中完成的,因此当层的宽度改变时,其子层上的变换就会被计算。我在这个项目中找到了计算变换的数学方法:https://github.com/MassiveHealth/Opaque。
这些动画为什么不对齐呢?也许数学计算有误?我查看了一些项目的示例代码,如https://github.com/honcheng/PaperFold-for-iOS和https://github.com/xyfeng/XYOrigami,但我无法找出问题所在。
更新: 根据Till的回答,我已经为滑动层创建了这个关键帧动画。然而,这些动画仍然不匹配,因此我的关键帧计算可能有误?
实际的展开层是在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"];