-->

获得CABasicAnimation的瞬时值(Get instant value of a CABa

2019-10-17 20:34发布

虽然我实现一个游戏,我只是的事,他真的很容易,我认为前面,但不知道如何解决它。 我在Objective-C的有点新的一样,你可以用我的名誉看到:(

问题是,我有一个动画,其正常工作。 下面是代码:

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,所有的时间的即时位置。

我希望我是understable。 谢谢你的帮助 :)

Answer 1:

我觉得你有3个选择在这里(请评论,如果更多存在):

选项1:分裂您的第一个动画分成两当上半场结束开始动画下半年再加上其他动画

...
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(这是更好)的回调和连续检查您的动画层的参数。 测试所需的值,参数触发第二动画。

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
    ...
}

2选项:设置一个CADisplayLink(现在可以称为“gameloop”),并通过计算和设置动画对象的合适的参数自行管理的动画。 不知道你想创建我想说的游戏循环可能是其他游戏的具体原因是有用的什么样的游戏。 另外这里我提到的cocos2d这是游戏的发展有很大的框架。



Answer 2:

你可以从你的层的表示层的价值。

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


Answer 3:

您可以尝试让您层的表示层,这应该是接近被呈现在屏幕上什么价值:

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


Answer 4:

我想补充一个选项,以什么@codedad指出。 有趣的,它提供了让你的动画层的瞬时值准确(你可以看到的CALayer的的可能性动画属性列表 ),这是非常简单的。

如果重写方法

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

在UIView类(是的,你需要实现从UIView的衍生为贵“ImageSuivante”视图中的自定义类),然后传递参数就不给你正是你需要的。 它包含用于绘制精确值。

例如,在这种方法中,你可以更新一个适当的时刻变量(与后来的工作),然后调用超,如果你不与你的手绘图:

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

这里注意, 一般是一样的对象self.layer(其中是您自定义的UIView),所以如self.layer.opacity会给你的目标不透明度,而不是一个瞬间的代码之后,而self.instantOpacity上面包含你想要的瞬时值。

要知道,这是一个绘图方法,它可能会频繁调用,因此没有不必要的计算或任何重的操作那里。

这种想法的根源是苹果公司的自定义设置动画地产项目。



文章来源: Get instant value of a CABasicAnimation