【问题标题】:Core Animation 'flip' animation核心动画“翻转”动画
【发布时间】:2010-05-28 12:05:02
【问题描述】:

我希望使用 Core Animation 在 Mac 应用程序中模拟翻转时钟动画。目前我有三个 CALayer 代表数字的上半部分和下半部分,第三个用来代表翻转动画(在下面的文章中找到了一个解决方案:Creating an iPad flip-clock with Core Animation

翻转层的动画分为两个阶段:从顶部翻转到数字中间,然后从中间到底部。为此,我使用了一个在动画结束时调用的委托函数:

- (void)animationDidStop:(CAAnimation *)oldAnimation finished:(BOOL)flag
{
    int digitIndex = [[oldAnimation valueForKey:@"digit"] intValue];    
    int currentValue = [[oldAnimation valueForKey:@"value"] intValue];

    NSMutableArray *digit = [digits objectAtIndex:digitIndex];
    CALayer *flipLayer = [digit objectAtIndex:tickerFlip];
    CALayer *bottomLayer = [digit objectAtIndex:tickerBottom];

    if([[oldAnimation valueForKey:@"state"] isEqual:@"top"] && flag) {
        NSLog(@"Top animation finished");

        [CATransaction begin];
        [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
        flipLayer.contents = [bottomImages objectAtIndex:currentValue];
        flipLayer.anchorPoint = CGPointMake(0.0, 1.0);
        flipLayer.hidden = NO;
        [CATransaction commit];

        CABasicAnimation *anim = [self generateAnimationForState:@"bottom"];
        [anim setValue:[NSString stringWithFormat:@"%d", digitIndex] forKey:@"digit"];
        [anim setValue:[NSString stringWithFormat:@"%d", currentValue] forKey:@"value"];
        [flipLayer addAnimation:anim forKey:nil];
    } else if([[oldAnimation valueForKey:@"state"] isEqual:@"bottom"] && flag) {
        NSLog(@"Bottom animation finished");

        // Hide our flip layer
        [CATransaction begin];
        [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
        bottomLayer.contents = [bottomImages objectAtIndex:currentValue];
        flipLayer.hidden = YES;
        flipLayer.anchorPoint = CGPointMake(0.0, 0.0);
        [CATransaction commit];
    }
}

这个委托函数使用了一个辅助函数,它根据翻转层的状态生成变换:

- (CABasicAnimation *)generateAnimationForState:(NSString *)state
{
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
    anim.duration = 0.15;
    anim.repeatCount = 1;

    // Check which animation we're doing
    if([state isEqualToString:@"top"]) 
    {
        anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0.0f, 1, 0, 0)];
        anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI/2, 1, 0, 0)];
    } 
    else 
    {
        anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-M_PI/2, 1, 0, 0)];
        anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0.0f, 1, 0, 0)];
    }

    anim.delegate = self;
    anim.removedOnCompletion = NO;

    // Set our animations state
    [anim setValue:state forKey:@"state"];

    return anim;
}

此解决方案有效,但在播放动画时会导致轻微闪烁。我相信这是由于我的翻转层在“顶部”和“底部”动画之间重置的转换。重要的是要注意,在动画的第一阶段完成后,我将翻转层的锚点设置到图像的顶部,确保翻转正确枢轴。

目前我不确定我的动画是否设置得最佳。一般来说,我是转换和核心动画的新手。谁能指出我正确的方向?

【问题讨论】:

标签: cocoa core-animation


【解决方案1】:

之后

anim.removedOnCompletion = NO; 

尝试插入此代码:

anim.fillMode = kCAFillModeForwards;

然后告诉我。本质上,代码 sn-p 应该防止导致闪烁的“重置”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    相关资源
    最近更新 更多