2

我正在构建一个 iOS 应用程序,我需要一种方法来将旋转 (by CABasicAnimation) 图像反射到下面的表面,就像半透明的材质效果一样。这是我命名indicatorindicatorReflection初始化图像的代码:

#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 组合,但我永远无法使反射视图遵循正确的反射路径。我不是三角学专家,但这对于任何懂数学的人来说都应该是微不足道的,除此之外,我已经尝试了所有可能的组合,其中一个应该是正确的答案。我的旋转计算代码有问题,还是与动画/变换方法有关?

谢谢,

能。

4

1 回答 1

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))

注意第一行的+号;您希望这两个对象以相反的方向旋转。但是,除非您翻转其中一个视图(仅通过旋转无法模拟镜像),否则您仍然不会拥有正确的外观。尝试制作一个在 y 轴上具有 -1 比例变换的子视图。

但是,这可能不会达到您想要的效果,因为变换无法知道您尝试旋转的方向。(假设您从中午旋转到 6 点;您可以指定从上到下,但 CABasicAnimation 不知道您是指顺时针还是逆时针;变换没有“符号”,因此它无法区分 180 度和 -180 度。)

获得预期效果的方法是使用CAValueFunction. 您无需指定 from 和 to 变换,而是指定您想要做什么(围绕 Z 轴旋转)以及您想要从哪个角度旋转(在这种情况下,它将尊重符号)。引用CAValueFunction 文档

通过创建 CAValueTransform 函数并指定 kCAValueFunctionRotateZ,然后创建一个 fromValue 为 0、toValue 为 M_PI 的动画,然后将动画的 valueTransform 属性设置为值转换实例。

所以,你会想要这样的东西:

-(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"];
}
于 2013-01-15T01:56:41.630 回答