我正在构建一个iOS应用程序,我需要一种方法将旋转(通过CABasicAnimation
)图像反射到下面的表面,就像半透明材质效果一样。以下是我的代码,用于初始化名为indicator
和indicatorReflection
的图片:
#define rotation_reflected(ANG) CGAffineTransformMakeRotation(M_PI/2 - (ANG * M_PI / 180.0))
#define rotation(ANG) CGAffineTransformMakeRotation(-M_PI/2 - (ANG * M_PI / 180.0))
[self rotateIndicator:0];
-(void)rotateIndicator:(float)degrees{
self.indicatorView.transform = rotation(degrees);
self.indicatorReflectionView.transform = rotation_reflected(degrees);
}
我使用以下代码为它们设置动画:
-(void)startWanderingIndicator{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D xform = CATransform3DMakeAffineTransform(rotation(180));
anim.toValue = [NSValue valueWithCATransform3D:xform];
anim.duration = 4.0f;
anim.fillMode = kCAFillModeForwards;
anim.removedOnCompletion = NO;
[self.indicatorView.layer addAnimation:anim forKey:@"rotation"];
anim = [CABasicAnimation animationWithKeyPath:@"transform"];
xform = CATransform3DMakeAffineTransform(rotation_reflected(180));
anim.toValue = [NSValue valueWithCATransform3D:xform];
anim.duration = 4.0f;
anim.fillMode = kCAFillModeForwards;
anim.removedOnCompletion = NO;
[self.indicatorReflectionView.layer addAnimation:anim forKey:@"rotation"];
}
第一个没有问题。问题始于反射视图。我已经尝试了几乎所有+/- PI / 2和+/- ANGLE组合,但我永远不能让反射视图遵循正确的反射路径。我不是一个三角学家,但对于那些懂数学的人来说,这应该是非常微不足道的事情,除此之外,我已经尝试了所有可能的组合,其中一个应该是正确的答案。我的旋转计算代码有问题,还是与动画/变换方法有关?
谢谢,
可以。
答案 0 :(得分:1)
你的功能应该是:
#define rotation_reflected(ANG) CGAffineTransformMakeRotation(M_PI/2 + (ANG * M_PI / 180.0))
#define rotation(ANG) CGAffineTransformMakeRotation(-M_PI/2 - (ANG * M_PI / 180.0))
注意第一行的+号;您希望两个对象在相反的方向上旋转。但是,除非您翻转其中一个视图(镜像不能仅通过旋转模拟),否则您仍然无法获得正确的外观。尝试制作一个子视图,其缩放比例为-1,例如y轴。
这可能无法达到您想要的效果,因为转换无法知道您要旋转的方向。(想象一下,您从中午转到6点;您需要指定向上,但CABasicAnimation不知道你的意思是顺时针还是逆时针;变换没有“符号”,所以它不能从-180度告诉180度。)
获得所需效果的方法是使用CAValueFunction
。您可以指定要执行的操作(围绕Z轴旋转)以及从哪个角度旋转(在这种情况下,它将遵循符号),而不是指定from和to变换。引用CAValueFunction docs:
使用值转换功能,可在0°到180°左右旋转 z轴通过创建指定的CAValueTransform函数 kCAValueFunctionRotateZ然后使用。创建动画 fromValue为0,是M_PI的toValue,并设置动画 value将属性转换为值转换实例。
所以,你想要的东西是:
-(void)startWanderingIndicator{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ];
anim.toValue = rotation(180);
anim.duration = 4.0f;
anim.fillMode = kCAFillModeForwards;
anim.removedOnCompletion = NO;
[self.indicatorView.layer addAnimation:anim forKey:@"rotation"];
anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ];
anim.toValue = rotation_reflected(180);
anim.duration = 4.0f;
anim.fillMode = kCAFillModeForwards;
anim.removedOnCompletion = NO;
[self.indicatorReflectionView.layer addAnimation:anim forKey:@"rotation"];
}