【问题标题】:How to reflect a rotated image view如何反映旋转的图像视图
【发布时间】:2013-01-15 01:32:58
【问题描述】:

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

谢谢,

可以。

【问题讨论】:

    标签: ios core-graphics scaling transformation caanimation


    【解决方案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 docs

    您使用从 0° 旋转到 180° 的值变换函数 通过创建 CAValueTransform 函数指定 z 轴 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"];
    }
    

    【讨论】:

    • 我已经尝试过您的代码,但是这一次,指示器从起始位置变为 45 度,然后返回到其初始位置,并带有平滑、缓动的动画。我不能让它工作。我也尝试过设置-180度来强制反转,但它并没有完全移动。不知道怎么回事
    • 我最终通过以下方法成功实施:stackoverflow.com/questions/1149635/… 使用带有 cakeyframeanimation 和关键帧值和关键时间的关键帧。我已经为动画关键时间的 0.5time 设置了值,并且动画正确
    • @Jesse,我在研究 CAValueTransform 和 CAAnimation 的 valueTransform 属性时发现了你的帖子。我能找到的 valueTransform 属性的唯一提及是您在 CAValueTransform 类参考中发布的报价。 CAAnimation 的 valueTransform 属性记录在哪里?我在任何地方都找不到它。它在祖先类之一中吗?在 CAAnimation 符合的协议之一中? ::困惑::
    • @DuncanC 我认为这是文档中的错字;他们的意思是valueFunction,而不是valueTransform
    • @JesseRusak,是的,文档中似乎确实存在拼写错误。我刚刚发布了关于它的“提供反馈”报告。你介意做同样的事情吗?我浪费了几个小时徒劳地寻找不存在的“valueTransform”。呜呜呜……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 2015-07-03
    • 1970-01-01
    • 2011-11-19
    相关资源
    最近更新 更多