【发布时间】: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;
}
此解决方案有效,但在播放动画时会导致轻微闪烁。我相信这是由于我的翻转层在“顶部”和“底部”动画之间重置的转换。重要的是要注意,在动画的第一阶段完成后,我将翻转层的锚点设置到图像的顶部,确保翻转正确枢轴。
目前我不确定我的动画是否设置得最佳。一般来说,我是转换和核心动画的新手。谁能指出我正确的方向?
【问题讨论】:
-
看到这个问题stackoverflow.com/questions/2845281/… 他正在使用这个 Lemur Flip 代码作为指导。它可以很好地完成您想要的工作。这是谷歌上的第一个结果
标签: cocoa core-animation