2013-05-23 3 views
0

У меня возникла проблема, которую я не могу понять. В моем приложении я использую пользовательский класс UIImageView для представления перемещаемых объектов. Некоторые из них загружаются статическими изображениями .png и используют анимацию кадров, в то время как другие загружаются с помощью путей CAShapeLayer из файлов .svg. Для некоторых из них я становлюсь заикающимся, когда слой оживляет один путь к другому, а UIImageView движется.CAShapeLayer путь анимации заикается, пока UIImageView движется

Вы можете увидеть это в связанном видео. Когда я касаюсь рога русалки, нота появляется (путь svg) и анимируется в рыбу (другой путь svg), все время дрейфуют вверх. Заикание происходит во время этой анимации/дрейфа. Это наиболее заметно в третий раз, когда я создаю рыбу, около 19 секунд в видео. (Прыжки в конце каждой анимации мне нужно исправить отдельно, так что не беспокойтесь об этом)

http://www.youtube.com/watch?v=lnrNWuvqQ4w

Это не происходит, когда я протестировать приложение в IOS Simulator - все гладко. На моем iPad 2 он заикается. Когда я выключаю движение примечания/рыбы (дрейфуя вверх), он оживляет плавно на iPad, поэтому, очевидно, это связано с перемещением вида одновременно. Мне чего-то не хватает, но я не могу понять.

Вот как я настроил анимацию. PocketSVG - это класс, который я нашел в Github, который преобразует .svg в путь Безье.

animShape = [CAShapeLayer layer]; 
[animShape setShouldRasterize:YES]; 
[animShape setRasterizationScale:[[UIScreen mainScreen] scale]]; 

PocketSVG *tSVG; 
UIBezierPath *tBezier; 

PocketSVG *tSVG2; 
UIBezierPath *tBezier2; 
CAShapeLayer *tLayer2; 
CABasicAnimation *animBezier; 
CABasicAnimation *animScale; 

tSVG = [[PocketSVG alloc] initFromSVGFileNamed:[NSString stringWithFormat:@"%@", tName]]; 

// Use PocketSVG to convert the SVG to a Bezier Path 
tBezier = tSVG.bezier; 
animShape.path = tBezier.CGPath; 
animShape.lineWidth = 1; 
animShape.strokeColor = [[UIColor blackColor] CGColor]; 
animShape.fillColor = [[UIColor blackColor] CGColor]; 
animShape.fillRule = kCAFillRuleNonZero; 

// Set the frame & bounds to position the piece and set anchor point for rotation 
// parentPaper is the Mermaid the note spawns from 
CGPoint newCenter; 
CGFloat imageScale = fabsf(parentPaper.transform.a); 
newCenter = // Code excised, set center based on custom spawn points in relation to parent position and scale 

animShape.bounds = CGPathGetBoundingBox(animShape.path); 

CGRect lBounds = CGRectMake(newCenter.x, newCenter.y, animShape.bounds.size.width, animShape.bounds.size.height); 
[animShape setFrame:lBounds]; 

halfSize = CGPointMake(animShape.bounds.size.width/2, animShape.bounds.size.height/2); 
animShape.anchorPoint = CGPointMake(prp.childSpawnX, prp.childSpawnY); 

// Create the end path for animation 
tSVG2 = [[PocketSVG alloc] initFromSVGFileNamed:[NSString stringWithFormat:@"%@2", tName]]; 
tBezier2 = tSVG2.bezier; 
tLayer2 = [CAShapeLayer layer]; 
tLayer2.path = tBezier2.CGPath; 

// Create the animation and add it to the layer 
animBezier = [CABasicAnimation animationWithKeyPath:@"path"]; 
animBezier.delegate = self; 
animBezier.duration = prp.frameDur; 
animBezier.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
animBezier.fillMode = kCAFillModeForwards; 
animBezier.removedOnCompletion = NO; 
animBezier.autoreverses = behavior.autoReverse; 

if (prp.animID < 0) { 
    animBezier.repeatCount = FLT_MAX; 
} 
else { 
    animBezier.repeatCount = prp.animID; 
} 

animBezier.fromValue = (id)animShape.path; 
animBezier.toValue = (id)tLayer2.path; 
[animShape addAnimation:animBezier forKey:@"animatePath"]; 

// also scale the animation if spawned from a parent 
// i.e. small note to normal-sized fish 
if (parentPaper != nil) { 

    animScale = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    animScale.delegate = self; 
    animScale.duration = prp.frameDur; 
    animScale.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    animScale.fillMode = kCAFillModeForwards; 
    animScale.removedOnCompletion = YES; 
    animScale.autoreverses = NO; 
    animScale.repeatCount = 1; 
    animScale.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(imageScale, imageScale, 0.0)]; 
    animScale.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 0.0)]; 
    [animShape addAnimation:animScale forKey:@"animateScale"]; 
} 

[self.layer addSublayer:animShape]; 

И это в основном, как я перемещаю UIImageView. Я использую CADisplayLink на 60 кадров, выяснить новое место, основываясь на существующем положении animShape.position и обновлять, как это, где self является UIImageView:

[self.animShape setPosition:paperCenter]; 

Все остальное проходит гладко, просто это один набор объектов что заикается и прыгает, когда работает на самом iPad. Любые идеи о том, что я делаю неправильно? Возможно, это не так? Я все время путаюсь со слоями, рамками и границами.

ответ

0

Чтобы исправить это, я изменил способ перемещения UIImageView. Вместо того, чтобы менять положение кадра через мой игровой цикл, я переключил его на CAKeyframeAnimation на позицию, поскольку это временное движение, которое выполняется только один раз. Я использовал CGPathAddCurveToPoint, чтобы воспроизвести движение синусоидальной волны, которое у меня первоначально было. Это было довольно просто, и я, вероятно, должен был сделать это с самого начала.

Я могу только догадываться, что заикание было связано с перемещением его по петле CADisplayLink во время анимации отдельно.

Смежные вопросы