结合 drawRect 和 KeyPathAnimation 来取消闪烁

Posted

技术标签:

【中文标题】结合 drawRect 和 KeyPathAnimation 来取消闪烁【英文标题】:Combining drawRect with KeyPathAnimation to undraw flickers 【发布时间】:2013-03-13 14:54:05 【问题描述】:

我正在 UIView 的 drawRect 方法中绘制路径。在某些情况下,路径会消失,我想对此进行动画处理 - 我们称之为路径的“取消绘制”。

对于动画,我正在创建一个 CAShapeLayer,给它 myPath,然后设置一个 CABasicAnimation (animationWithKeyPath:@"strokeEnd")。

我的问题是如何从 drawRect 中绘制的内容切换到动画。我必须从 drawRect 绘制的内容中删除 myPath 并调用 setNeedsDisplay - 否则动画将被从 drawRect 绘制的路径隐藏。

- (void)animationDidStart:(CAAnimation *)theAnimation
  
    myPath = nil;
    [self setNeedsDisplay];
  

但是这样我看到了我的路径,然后快速闪烁没有路径,然后路径再次由 CoreAnimation 渲染并且很好地未绘制。

我可以更好地避免闪烁吗?

背景 这就是我设置动画的方式:

- (void) startAnimation

  pathLayer.path = myPath.CGPath;
  pathLayer.hidden = false;

  CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
  pathAnimation.duration = 1; 
  pathAnimation.fromValue = [NSNumber numberWithFloat:1.0f];
  pathAnimation.toValue = [NSNumber numberWithFloat:0.0f];
  pathAnimation.fillMode = kCAFillModeForwards;
  pathAnimation.removedOnCompletion = NO;
  pathAnimation.delegate = self;
  [pathLayer addAnimation:pathAnimation forKey:@"strokeEnd"];

【问题讨论】:

你是如何设置你的基本动画的? 在问题中添加了动画设置代码。 kCAFillModeBoth 会为您解决闪烁问题吗? kCAFillModeBoth 没有变化。 【参考方案1】:

我认为闪烁的原因是您调用时运行的隐式动画

pathLayer.hidden = NO;

默认情况下,独立的 CALayers 会隐式地为大多数属性更改设置动画。如果你禁用了隐藏属性的隐式动画,它应该运行而不闪烁(不管你使用drawRect:还是drawLayer:inContext:):

[CATransaction begin];
[CATransaction setDisableActions:YES];
pathLayer.hidden = NO;
[CATransaction commit];

【讨论】:

【参考方案2】:

这是我的解决方案:不要将 UIKit 的 drawRect 与 CAAnimation 结合,而是绘制到 CALayer 中:

- (void)drawLayer:(CALayer *)theLayer inContext:(CGContextRef)theContext 

这允许从绘图到动画的无闪烁切换。

【讨论】:

以上是关于结合 drawRect 和 KeyPathAnimation 来取消闪烁的主要内容,如果未能解决你的问题,请参考以下文章

iOS drawRect的作用和调用机制

UIView的layoutSubviews和drawRect方法何时调用

iOS开发之drawRect的作用和调用机制

drawRect:和layoutSubview的区别

CALayer 和 drawRect

UIView的layoutSubviews和drawRect方法何时调用