获得CABasicAnimation的即时价值

当我正在执行一个游戏时,我只是一个事情的前面,我觉得这很容易,但是不知道如何解决这个问题。 我有点新的目标,你可以看到我的名誉:(

问题是,我有一个animation,这是正确的。 这里是代码:

CABasicAnimation * bordgauche = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; bordgauche.fromValue = [NSNumber numberWithFloat:0.0f]; bordgauche.toValue = [NSNumber numberWithFloat:749.0f]; bordgauche.duration = t; bordgauche.repeatCount = 1; [ImageSuivante.layer addAnimation:bordgauche forKey:@"bordgauche"]; 

我想获得我的形象的当前位置。 所以我使用:

 CALayer *currentLayer = (CALayer *)[ImageSuivante.layer presentationLayer]; currentX = [(NSNumber *)[currentLayer valueForKeyPath:@"transform.translation.x"] floatValue]; 

但我不明白。 我得到一次“当前= 0.0000”,这是起始值,当我使用nslog打印它,而不是其他人。 我不知道如何一直得到我的形象currentX的即时位置。

我希望我是可以理解的。 谢谢你的帮助 :)

我想你在这里有3个select(如果更多的话,请留言):

选项1:将第一个animation分成两部分,当前半部分结束时,开始animation的第二部分加上其他animation

 ... bordgauche.toValue = [NSNumber numberWithFloat:749.0f / 2]; bordgauche.duration = t/2; bordgauche.delegate = self // necessary to catch end of anim [bordgauche setValue:@"bordgauche_1" forKey: @"animname"]; // to identify anim if more exist ... - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag { if ([theAnimation valueForKey: @"animname"]==@"bordgauche_1") { CABasicAnimation * bordgauche = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; bordgauche.fromValue = [NSNumber numberWithFloat:749.0f / 2]; bordgauche.toValue = [NSNumber numberWithFloat:749.0f]; bordgauche.duration = t/2; bordgauche.repeatCount = 1; [ImageSuivante.layer addAnimation:bordgauche forKey:@"bordgauche_2"]; // plus start your second anim } 

选项2:设置一个NSTimer或一个CADisplayLink(这是更好的)callback,并连续检查你的animation层的参数。 testing所需值的参数来触发第二个animation。

 displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(check_ca_anim)]; [displayLink setFrameInterval:1]; [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; ... or animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)(1.0 / 60.0) target:self selector:@selector(check_ca_anim) userInfo:nil repeats:TRUE]; [[NSRunLoop mainRunLoop] addTimer:animationTimer forMode:NSRunLoopCommonModes]; - (void) check_ca_anim { ... CGPoint currentPosition = [[ImageSuivante.layer presentationLayer] position]; // test it and conditionally start something ... } 

选项3:设置CADisplayLink(现在可以称为“gameloop”),并通过计算和设置animation对象的适当参数来自己pipe理animation。 不知道你想创build什么样的游戏我会说游戏循环可能对其他游戏特定的原因有用。 在这里我还提到了Cocos2d,它是游戏开发的一个很好的框架。

您可以从图层的表示层获取值。

 CGPoint currentPos = [ImageSuivante.layer.presentationLayer position]; NSLog(@"%f %f",currentPos.x,currentPos.y); 

您可以尝试从图层的表示层获取值,该值应接近屏幕上显示的值:

 [ [ ImageSuivante.layer presentationLayer ] valueForKeyPath:@"transform.translation.x" ] ; 

我会添加一个选项,以@codedad指出。 有趣的是,它可以准确获得animation图层的即时值(可以看到CALayer的animation属性列表 ),而且非常简单。

如果你重写方法

 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx; 

在你的UIView类(是的,你需要实现从你的“ImageSuivante”视图派生自UIView的自定义类),然后通过那里传递参数会给你正是你所需要的。 它包含用于绘图的精确值。

例如,在这种方法中,你可以更新一个适当的即时variables(稍后处理),然后调用超级,如果你不用你的手绘制:

 - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context { self.instantOpacity = layer.opacity; self.instantTransform = layer.transform; [super drawLayer:layer inContext:context]; } 

请注意,这里的图层通常与self.layer (其中self是您的自定义UIView)的对象不是同一个对象,因此self.layer.opacity会为您提供目标不透明度,但不是即时值,而代码后面的self.instantOpacity上面会包含你想要的即时值。

只要知道这是一个绘图方法,它可能被称为非常频繁,所以没有不必要的计算或任何繁重的操作。

这个想法的来源是苹果的自定义animation属性项目。