【问题标题】:problem using CABasicAnimation to animate multiple CALayers使用 CABasicAnimation 为多个 CALayers 设置动画的问题
【发布时间】:2011-03-27 22:42:54
【问题描述】:

我在我的棋盘游戏 iPhone 应用程序中遇到了很多动画问题。我使用以下函数为移动计数器的计算机播放器设置动画:

-(void)animateCounterMoveFor:(int)playerType counterId:(int)countId {

    // set up the move to an end point
    CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"position"];
    [move setDuration:3.5];
    [move setToValue:[NSValue valueWithCGPoint:CGPointMake((xPos), (yPos))]];
    [move setFillMode:kCAFillModeForwards];
    [move setRemovedOnCompletion:NO];
    CAMediaTimingFunction *tf = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [move setTimingFunction:tf];

    // enable the animation stop to set layer to right position
    [move setValue:[NSNumber numberWithInt:countId] forKey:@"counterId"];
    [move setValue:[NSNumber numberWithInt:playerType] forKey:@"playerType"];
    [move setDelegate:self];

    // add move to the layer
    [layer addAnimation:move forKey:@"moveAnimation"];

}

.. 然后委托设置图层位置并在动画完成时移除动画(否则计数器会移回其起始位置)。

-(void)animationDidStop:(CABasicAnimation *)anim finished:(BOOL)flag {

    NSNumber *counterId = [anim valueForKey:@"counterImageId"];
    NSNumber *playerId = [anim valueForKey:@"playerType"];

    int countId = [counterId intValue];
    int playId = [playerId intValue];

// code here gets position information using counter and player id

    // set the final position of the layer when the anim stops, then remove the anim
    [layer setPosition:CGPointMake(xPos, yPos)];
    [layer removeAnimationForKey:@"moveAnimation"];

}

当一个计数器移动时,这一切都很好,但是当一个计数器带另一个计数器时,我使用相同的方法来移动两者。我认为动画的副本已传递给图层,因此我可以调用它来移动第一个计数器图层,然后立即再次调用它以移动第二个。我注销了对象 ID 并创建了两个不同的移动动画,但只有第二个计数器移动。 animationDidStop:被调用两次,每次都传递正确的计数器信息。

关于如何使它工作的任何想法?我已经浏览了很多 CAAnimation/CALayer 问题,所以我想这不仅仅是我遇到的问题;)

【问题讨论】:

    标签: iphone objective-c core-animation


    【解决方案1】:

    为什么不提前知道最终的位置?

    我会在 animateCounterMoveFor: 方法中设置对象的位置,否则它会迅速回到原始位置,因为在你设置它之前,calayer 不会真正移动。

    -(void)animateCounterMoveFor:(int)playerType counterId:(int)countId {
    
        // set up the move to an end point
        CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"position"];
        [move setDuration:3.5];
        [move setToValue:[NSValue valueWithCGPoint:CGPointMake((xPos), (yPos))]];
        [move setFillMode:kCAFillModeForwards];
        [move setRemovedOnCompletion:NO];
        CAMediaTimingFunction *tf = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [move setTimingFunction:tf];
    
    
        [layer addAnimation:move forKey:@"position"];   // Replaces the previous position animation on the layer
        [layer setPosition:CGPointMake(xPos, yPos)];        // Sets the final position after animation is finished
    
        // enable the animation stop to set layer to right position
        [move setValue:[NSNumber numberWithInt:countId] forKey:@"counterId"];
        [move setValue:[NSNumber numberWithInt:playerType] forKey:@"playerType"];
        [move setDelegate:self];
    
    }
    

    【讨论】:

    • 当我尝试在 animateCounterMoveFor: 方法中设置位置时,计数器直接捕捉到结束位置,然后将动画从结束位置运行到结束位置(我认为),所以没有发生移动。这就是为什么我在搞乱动画DidStop:
    • 在我发布这个问题时对我的代码进行了大量检查之后,我后来以更好的视角返回并检查了我所有的假设 - 我传入了播放器和计数器 id错误的方式... duh ..所以实际上这段代码确实有效。不过可能有更好的方法!
    • 您可能需要设置 fromValue。
    • 设置 fromValue 也确实修复了它而不使用 animationDidStop
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    相关资源
    最近更新 更多