与CALayers CAAnimation偶尔创build闪烁的animation(包括video)

我的应用程序需要一个静止的照片,并animation口区域模仿说话。 但是,大约1/4的时间内,一些隐藏的calayers将在整个animation中不断闪烁。

这是应用程序正常工作时的样子。 这是应用程序在发生故障时的样子。 编辑:一个更好的video

我假设这个问题是path相关的。 在应用程序中,用户在嘴部区域周围创build一个path(在video中简要显示),这将是animation区域。 有时path会导致一个平滑的animation,有时候会导致上面的小故障。 此外,如果我按下“back”并尝试用animation重新加载控制器,则毛刺会持续存在,而如果在重新加载之前更改path,则偶尔会消失。

如果不是path相关,我已经消除的一些罪魁祸首是:

  • 图像types/来源 – 有时它将适用于图像a,但不适用于图像b,其他时间适用于图像b,但不适用于a。 我已经尝试了照片库的图像以及从互联网上保存的图像。

  • iPhone vs模拟器 – 两个设备上都出现问题

  • animation数量 – 有时会在第一次尝试时发生; 其他时间会发生在5日或6日尝试。

下面是从视图的代码animation。 我首先创build一个全黑的图层,然后是一个图层减去嘴部区域,最后是一个刚才的嘴部区域。 然后,我改变了嘴巴的位置,使位移变成黑色,看起来像张开的嘴。

编辑:另外,如果我通过从面层去除蒙版去除嘴孔,animation运行平稳。

- (id)initWithFrame:(CGRect)frame leftPt:(CGPoint)point0 rightPt:(CGPoint)point2 vertex1:(CGPoint)vertex1 vertex2:(CGPoint)vertex2 andPicture:(UIImage *)pic{ self = [super initWithFrame:frame]; if (self) { p0 = point0; p2 = point2; v1 = vertex1; v2 = vertex2; picture = pic; [self addBlackLayer]; [self addFaceLayer]; [self addMouthLayer]; self.opaque = YES; } return self; } - (void)addBlackLayer { CALayer *blackLayer = [CALayer layer]; blackLayer.frame = self.bounds; blackLayer.backgroundColor = [UIColor blackColor].CGColor; [self.layer addSublayer:blackLayer]; } - (void)addFaceLayer { CALayer *faceLayer = [CALayer layer]; faceLayer.frame = self.bounds; faceLayer.contents = (id)[picture CGImageWithProperOrientation]; CAShapeLayer *faceMask = [CAShapeLayer layer]; CGMutablePathRef fPath = CGPathCreateMutable(); CGPathMoveToPoint(fPath, NULL, CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds)); CGPathAddLineToPoint(fPath, NULL, CGRectGetMaxX(self.bounds), CGRectGetMinY(self.bounds)); CGPathAddLineToPoint(fPath, NULL, CGRectGetMaxX(self.bounds), CGRectGetMaxY(self.bounds)); CGPathAddLineToPoint(fPath, NULL, CGRectGetMinX(self.bounds), CGRectGetMaxY(self.bounds)); CGPathAddLineToPoint(fPath, NULL, CGRectGetMinX(self.bounds), CGRectGetMinY(self.bounds)); CGPathMoveToPoint(fPath, NULL, p0.x, p0.y); midpt = CGPointMake( (p2.x + p0.x)/2, (p2.y+ p0.y)/2); CGPoint c1 = CGPointMake(2*v1.x - midpt.x, 2*v1.y - midpt.y); //control points CGPoint c2 = CGPointMake(2*v2.x - midpt.x, 2*v2.y - midpt.y); CGPathAddQuadCurveToPoint(fPath, NULL, c1.x, c1.y, p2.x, p2.y); CGPathAddQuadCurveToPoint(fPath, NULL, c2.x, c2.y, p0.x, p0.y); faceMask.path = fPath; faceLayer.mask = faceMask; [faceMask setFillRule:kCAFillRuleEvenOdd]; [self.layer addSublayer:faceLayer]; CGPathRelease(fPath); } - (void)addMouthLayer { CGMutablePathRef mPath = CGPathCreateMutable(); CGPathMoveToPoint(mPath, NULL, p0.x, p0.y); midpt = CGPointMake( (p2.x + p0.x)/2, (p2.y+ p0.y)/2); CGPoint c1 = CGPointMake(2*v1.x - midpt.x, 2*v1.y - midpt.y); //control points CGPoint c2 = CGPointMake(2*v2.x - midpt.x, 2*v2.y - midpt.y); CGPathAddQuadCurveToPoint(mPath, NULL, c1.x, c1.y, p2.x, p2.y); CGPathAddQuadCurveToPoint(mPath, NULL, c2.x, c2.y, p0.x, p0.y); self.mouthLayer = [CALayer layer]; CAShapeLayer *mouthMask = [CAShapeLayer layer]; self.mouthLayer.frame = self.bounds; self.mouthLayer.contents = (id)[picture CGImageWithProperOrientation]; mouthMask.path = mPath; mouthMask.frame = mouthLayer.bounds; self.mouthLayer.mask = mouthMask; [self.layer addSublayer:mouthLayer]; self.mouthLayer.frame = CGRectMake(mouthLayer.frame.origin.x, mouthLayer.frame.origin.y, mouthLayer.frame.size.width, mouthLayer.frame.size.height); CGPathRelease(mPath); 

这是从视图控制器创buildanimation的代码

 - (CAAnimation *)createAnimationWithRepeatCount:(int)count { CGPoint convertedStartingCenter = [self.view convertPoint:animatedFace.center toView:animatedFace]; CGPoint endPt = CGPointMake(convertedStartingCenter.x, convertedStartingCenter.y + 15); CABasicAnimation *mouthDown = [CABasicAnimation animationWithKeyPath:@"position"]; mouthDown.duration = ANIMATION_TIME; mouthDown.beginTime = 0; mouthDown.fromValue = [NSValue valueWithCGPoint:convertedStartingCenter]; mouthDown.toValue = [NSValue valueWithCGPoint:endPt]; CABasicAnimation *mouthUp = [CABasicAnimation animationWithKeyPath:@"position"]; mouthUp.duration = ANIMATION_TIME; mouthUp.beginTime = ANIMATION_TIME; mouthUp.fromValue = [NSValue valueWithCGPoint:endPt]; mouthUp.toValue = [NSValue valueWithCGPoint:convertedStartingCenter]; CAAnimationGroup *totalAnimation = [CAAnimationGroup animation]; [totalAnimation setAnimations:[NSArray arrayWithObjects:mouthDown,mouthUp, nil]]; [totalAnimation setDuration:2*ANIMATION_TIME]; [totalAnimation setRemovedOnCompletion:NO]; [totalAnimation setFillMode:kCAFillModeForwards]; totalAnimation.repeatCount = count; return totalAnimation; } 

只是另一种方法(不知道是否尝试过),只能使用CABasicAnimation并将您的类设置为animation代理,并且在委托方法中您可以尝试启动下一个CABasicAnimation 。 如果你没有尝试,我可以为你提供一个例子。