跟踪核心动画动画

tit*_*coy 12 cocoa-touch core-animation

我有两个围绕屏幕移动的圆圈.圆圈都是包含其他UIViews的UIViews.每个圆圈外面的区域是透明的.

我写了一个函数来创建一个CGPath,它将两个圆形连接成四边形.我在透明的CALayer中填充此路径,该CALayer跨越整个屏幕.由于该层位于两个圆形UIViews的后面,因此它似乎可以连接它们.

最后,两个UIViews使用Core Animation进行动画制作.在此动画期间,两个圆的位置和大小都会改变.

到目前为止,我唯一获得成功的方法是使用NSTimer定期中断动画,然后根据圆圈presentationLayer的位置重新计算并绘制光束.然而,当动画加速时,四边形滞后于圆圈.

有没有更好的方法来使用Core Animation实现这一目标?或者我应该避免使用核心动画并使用NSTimer实现我自己的动画?

fsa*_*int 13

我遇到了类似的问题.我使用了图层而不是动画的视图.你可以尝试这样的事情.

  1. 将每个元素绘制为CALayer并将它们包含为容器UIVIew层的子图层.UIViews更容易制作动画,但你的控制力会减少.请注意,对于任何视图,您都可以使用[view layer]获取它的图层;
  2. 为四边形创建自定义子图层.此图层应具有要为此图层设置动画的属性或多个属性.我们称这个属性为"customprop".由于它是自定义图层,因此您需要在动画的每个帧上重绘.对于您计划设置动画的属性,您的自定义图层类应返回YES needsDisplayForKey:.这样你就可以确保- (void)drawInContext:(CGContextRef)在每一帧上调用theContext.
  3. 将所有动画(圆圈和四边形)放在同一个交易中;

对于圆圈,你可以使用CALayers并设置内容,如果是图像,则采用标准方式:

layer.contents = [UIImage imageNamed:@"circle_image.png"].CGImage;
Run Code Online (Sandbox Code Playgroud)

现在,对于四层,子类CALayer并以这种方式实现:

- (void)drawInContext:(CGContextRef)theContext{
  //Custom draw code here
}   
+ (BOOL)needsDisplayForKey:(NSString *)key{
   if ([key isEqualToString:@"customprop"])
      return YES;
    return [super needsDisplayForKey:key];
}   
Run Code Online (Sandbox Code Playgroud)

交易看起来像:

[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];
Run Code Online (Sandbox Code Playgroud)

现在所有的绘制程序都会同时发生.确保你的drawInContext:实现很快.否则动画会滞后.

将每个子图层添加到UIViews的图层后,请记住调用[layer setNeedsDisplay].它不会自动调用.

我知道这有点复杂.但是,生成的动画比使用NSTimer并重新绘制每个调用要好.