我是一个动画初学者,并且已经用 CoreAnimation 试验了几天。如果这个问题没有意义,请随时警告我,但我正在努力实现以下目标。我有三个对象:
- 一个应该是图像,按照给定的模式移动
- 一个应该是交换两个图像的 UIImage
- 一个应该是内容发生变化的文本(CATextLayer?)
这三个动作应该同步发生。
例如,考虑一个显示正弦函数的程序,例如心电图,在 -1 和 +1 之间振荡:然后第一张图像将根据当前值移动(-1,-0.9,-0.8,... 0, +0.1, +0.2, ... 1),交换图像将显示“+”表示正值,“-”表示负值,文本将在“Positive”和“Negative”之间交替显示。
我已经尝试过使用 CAAnimationGroup,但我显然遗漏了一些东西。一些代码:
{
// image that moves
CALayer *img1 = [CALayer layer];
img1.bounds = CGRectMake(0, 0, 20, 20);
img1.position = CGPointMake(x1,y1);
UIImage *img1Image = [UIImage imageNamed:@"image.png"];
img1.contents = (id)img1Image.CGImage;
// image that changes
CALayer *swap = [CALayer layer];
swap.bounds = CGRectMake(0, 0, 30, 30);
swap.position = CGPointMake(x2,y2);
NSString* nameswap = @"img_swap_1.png"
UIImage *swapImg = [UIImage imageNamed:nameswap];
// text
CATextLayer *text = [CATextLayer layer];
text.bounds = CGRectMake(0, 0, 100, 100);
text.position = CGPointMake(x3,y3);
text.string = @"Text";
// create animations
CGFloat duration = 0.2;
CGFloat totalDuration = 0.0;
CGFloat start = 0;
NSMutableArray* animarray = [[NSMutableArray alloc] init];
NSMutableArray* swapanimarray = [[NSMutableArray alloc] init];
NSMutableArray* textanimarray = [[NSMutableArray alloc] init];
float prev_x = 0;
float prev_y = 0;
// I get my values for moving the object
for (NSDictionary* event in self.events) {
float actual_x = [[event valueForKey:@"x"] floatValue];
float actual_y = [[event valueForKey:@"y"] floatValue];
// image move animation
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position"];
CGPoint startPt = CGPointMake(prev_x,prev_y);
CGPoint endPt = CGPointMake(actual_x, actual_y);
anim.duration = duration;
anim.fromValue = [NSValue valueWithCGPoint:startPt];
anim.toValue = [NSValue valueWithCGPoint:endPt];
anim.beginTime = start;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[animarray addObject:anim];
// image swap animation
CABasicAnimation *swapanim = [CABasicAnimation animationWithKeyPath:@"contents"];
swapanim.duration = duration;
swapanim.beginTime = start;
NSString* swapnamefrom = [NSString stringWithFormat:@"%@.png", prev_name];
NSString* swapnameto = [NSString stringWithFormat:@"%@.png", current_name];
UIImage *swapFromImage = [UIImage imageNamed:swapnamefrom];
UIImage *swapToImage = [UIImage imageNamed:swapnameto];
swapanim.fromValue = (id)(swapFromImage.CGImage);
swapanim.toValue = (id)(swapToImage.CGImage);
swapanim.fillMode = kCAFillModeForwards;
swapanim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[swapanimarray addObject:swapanim];
//text animation
CABasicAnimation *textanim = [CABasicAnimation animationWithKeyPath:@"contents"];
textanim.duration = duration;
textanim.fromValue = @"Hey";
textanim.toValue = @"Hello";
textanim.beginTime = start;
[textanimarray addObject:textanim];
// final time settings
prev_x = actual_x;
prev_y = actual_y;
start = start + duration;
totalDuration = start + duration;
}
}
CAAnimationGroup* group = [CAAnimationGroup animation];
[group setDuration:totalDuration];
group.removedOnCompletion = NO;
group.fillMode = kCAFillModeForwards;
[group setAnimations:animarray];
CAAnimationGroup* swapgroup = [CAAnimationGroup animation];
[swapgroup setDuration:totalDuration];
swapgroup.removedOnCompletion = NO;
swapgroup.fillMode = kCAFillModeForwards;
[swapgroup setAnimations:swapanimarray];
CAAnimationGroup* textgroup = [CAAnimationGroup animation];
[textgroup setDuration:totalDuration];
textgroup.removedOnCompletion = NO;
textgroup.fillMode = kCAFillModeForwards;
[textgroup setAnimations:textanimarray];
[ball addAnimation:group forKey:@"position"];
[swap addAnimation:flaggroup forKey:@"position"];
[text addAnimation:textgroup forKey:@"contents"];
[self.layer addSublayer:ball];
[self.layer addSublayer:swap];
[self.layer addSublayer:text];
}
现在......问题:
1)交换图像在每次交换时恢复为原始图像。因此,如果我交换 A->B,我会看到它在预期的持续时间内从 A 变为 B,但随后又恢复为 A。我已经阅读了一些关于 SO 的线程,但无法让它工作.
2)以定时的方式更改文本层的字符串......这个基础设施有可能吗?基本上,我试图让文本和交换图像在第一个图像移动后立即更改,如示例中所述。
3) 为 CABasicAnimation 设置委托没有任何效果,尽管它对 CAAnimationGroup 有效:因此,您不能为每个动画管理像 animationDidStop 这样的事件,而只能针对整个组。有没有其他方法可以做到这一点?
4) 从 3) 开始,是否可以使用 CAAnimationGroup 拦截事件以创建停止/启动行为?假设我想要播放/停止按钮,并从我离开的地方恢复动画?
作为一个决定性的问题,我只想知道是否有人做过类似的事情,最重要的是,这种做事方式(使用 CAAnimationGroup)是否真的是可行的方法,或者使用 CAKeyFrameAnimation 或其他方法是否更好。