核心动画“翻转”动画 [英] Core Animation 'flip' animation

查看:85
本文介绍了核心动画“翻转”动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Core Animation在Mac应用程序中模拟翻转时钟动画。目前我有三个CALayer代表数字的上半部分和下半部分,第三个用于表示翻转动画(一个解决方案在下面的文章:使用Core动画创建iPad翻转时钟



翻转层的动画被分成两个阶段:从顶部到数字的中间,然后从中间到底部。为了实现这个,我使用每当动画结束时调用的委托函数:

   - (void)animationDidStop:(CAAnimation *)oldAnimation finished: 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]&& amp; 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]&& amp; flag){
NSLog(@Bottom animation finished

//隐藏我们的翻转图层
[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:@transformation];
anim.duration = 0.15;
anim.repeatCount = 1;

//检查我们正在做的动画
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;

//设置我们的动画状态
[anim setValue:state forKey:@state];

return anim;
}

此解决方案可行,但会在动画进行时产生轻微闪烁。我相信这是由于我在顶部和底部动画之间的翻转层重置的转换。重要的是要注意,在动画的第一阶段完成后,我将翻转图层的锚点设置到图像的顶部,确保翻转正确。



目前我不确定我的动画是否已经最佳设置。我是新的转换和核心动画一般。



<$ p

$ p> anim.removedOnCompletion = NO;

尝试插入以下代码:

  anim.fillMode = kCAFillModeForwards; 

让我知道。基本上,代码片段应该防止导致闪烁的重置。


I'm looking to use Core Animation to simulate a flip clock animation in a Mac application. Currently I have three CALayer's representing the top and bottom half of the digit, and a third used to represent the flip animation (a solution found in the follow article: Creating an iPad flip-clock with Core Animation.

The animation of the flip layer is broken into two stages: flipping from the top to the middle of the digit, and then from the middle to the bottom. To achieve this, I use a delegate function which is called whenever an animation ends:

- (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];
    }
}

This delegate function makes use of a helper function which generates the transform for the flip layer depending upon its state:

- (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;
}

This solution works but causes some slight flickering when an animation is in progress. I believe this is due to the transform on my flip layer resetting between the 'top' and 'bottom' animations. It's important to note that after the first stage of the animation completes, I set the flip layers anchor point to the top of the image, ensuring the flip pivots correctly.

Currently I'm unsure if my animation has been setup optimally. I'm new to transformations and Core Animation in general. Can anyone point me in the right direction?

解决方案

After

anim.removedOnCompletion = NO; 

try inserting this code:

anim.fillMode = kCAFillModeForwards;

And let me know. Essentially the code snippet is supposed to prevent the 'reset' that is causing the flicker.

这篇关于核心动画“翻转”动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆