2013-05-15 28 views
2

我的應用拍攝靜態照片併爲口區域設置動畫來模擬對話。然而,大約1/4的時間內,一些隱藏的calayers將在整個動畫中持續閃爍。CAAnimation與CALayers偶爾會創建閃爍的動畫(包含視頻)

這是應用程序的樣子,當它works properly。 這是應用程序的樣子,當它glitches編輯:a better video

我假設問題是路徑相關的。在應用程序中,用戶在嘴部區域周圍創建一個路徑(在視頻中簡要顯示),這將成爲動畫區域。有時候路徑會導致平滑的動畫,而其他時候則會導致上面的小故障。另外,如果我按下「後退」並嘗試用動畫重新加載控制器,則毛刺會持續存在,而如果在重新加載前更改路徑,它偶爾會消失。

如果它不路徑有關,有些我已經消除的元兇是:

  • 圖像類型/源 - 有時它會爲圖像而不是圖像 b工作,其他時候它會爲圖像b工作,但不是a。我試過 圖片庫以及從互聯網上保存的圖片。

  • iphone VS模擬器 - 問題時這兩個設備

  • 一些圖片上動畫製作 - 有時它會發生在第一 嘗試;其他時間將在5日或6日嘗試。

下面是從動畫視圖中的代碼。我首先創建一個全黑的圖層,然後創建一個圖層,減去嘴部區域,最後創建一個只有嘴部區域的圖層。然後,我改變嘴巴的位置,使位移變黑,看起來像張開的嘴。

編輯:此外,如果我通過從面層去除蒙版去除了嘴孔,動畫運行平穩。

- (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); 

下面是創建動畫,從視圖控制器

- (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; 

} 
+0

林不知道是否是一個錯字,如果它會解決您的問題(可以不)。但是您應該將返回類型從CAAnimation更改爲CAAnimationGroup。 – danypata

+0

不,那不是它 – Mahir

+0

很難看到究竟發生了什麼。在電影中,似乎路徑未能在圖像中創建洞。如果沒有,你可以放慢動畫速度嗎? –

回答

0

只是另一種方法的代碼(不知道你是否嘗試過),你可以只使用CABasicAnimation並設置你的類作爲動畫代表,並且在代表方法中,您可以嘗試啓動下一個CABasicAnimation。如果你沒有嘗試過,我可以爲你提供一個例子。

+0

當我僅使用一個cabasicanimation時,問題仍然存在 – Mahir

+0

這聽起來像是類似的情況嗎? HTTP://計算器。com/questions/1102896/switching-cabasicanimation-on-the-position-property-mid-animation-causes-a-flick – Mahir

+0

是的,它看起來像是你的行爲。您應該嘗試「鎖定」和「解鎖」交易。 – danypata