我遇到了类似的问题。我使用层(layer)代替视图(view)来进行动画。你可以尝试像这样做:
- 将每个元素绘制为一个 CALayer,并将它们作为子图层(sublayers)包含在容器 UIView 的层(layer)中。UIView 更容易进行动画,但是你将拥有更少的控制权。请注意,对于任何视图,你都可以使用 [view layer] 获取它的层(layer);
- 为你的四边形创建一个自定义子层。该层应具有你要为其动画的一个或多个属性。我们称此属性为 "customprop"。由于它是一个自定义层,你希望在每一帧(frame)动画上重绘。对于你计划进行动画处理的属性,你的自定义层类应返回 YES needsDisplayForKey:。这样你就能确保每一帧(frame)都会调用 -(void)drawInContext:(CGContextRef)theContext;
- 将所有动画(圆和四边形)放在同一事务(transaction)中;
对于圆形,如果是图像,则可以使用 CALayers 并设置内容,这是标准方式:
layer.contents = [UIImage imageNamed:@"circle_image.png"].CGImage
现在,针对四重层,子类化CALayer并以这种方式实现:
- (void)drawInContext:(CGContextRef)theContext{
}
+ (BOOL)needsDisplayForKey:(NSString *)key{
if ([key isEqualToString:@"customprop"])
return YES;
return [super needsDisplayForKey:key];
}
交易将如下所示:
[CATransaction begin];
CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"customprop"];
theAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1000, 1000)];
theAnimation.duration=1.0;
theAnimation.repeatCount=4;
theAnimation.autoreverses=YES;
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
theAnimation.delegate = self;
[lay addAnimation:theAnimation forKey:@"selecting"];
[CATransaction setValue:[NSNumber numberWithFloat:10.0f]
forKey:kCATransactionAnimationDuration];
circ1.position=CGPointMake(1000, 1000);
circ2.position=CGPointMake(1000, 1000);
[CATransaction commit];
现在所有的绘制操作将同时发生。确保您的drawInContext:实现快速,否则动画会出现滞后。
向UIView的图层添加每个子层后,请记得调用[layer setNeedsDisplay]。它不会自动调用。
我知道这有点复杂。然而,与使用NSTimer并在每次调用时重新绘制相比,产生的动画效果更好。
NSTimer
,因为它会很慢且占用CPU。对于任何与动画相关的内容,请使用CADisplayLink
,它与屏幕刷新率同步,并由CoreAnimation内部使用。 - skozin