Анимация CAEmitterLayer emitterPosition
Я пытаюсь оживить CAEmitterLayer
"s emitterPosition
как это:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"emitterPosition.x"] ;
animation.toValue = (id) toValue ;
animation.removedOnCompletion = NO ;
animation.duration = self.translationDuration ;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut] ;
animation.completion = ^(BOOL finished)
{
[self animateToOtherSide] ;
} ;
[_emitterLayer addAnimation:animation forKey:@"emitterPosition"] ;
CGPoint newEmitterPosition = CGPointMake(toValue.floatValue, self.bounds.size.height/2.0) ;
_emitterLayer.emitterPosition = newEmitterPosition ;
Обратите внимание, что animation.completion
объявлен в категории, которая просто вызывает соответствующий CAAnimation
метод делегата.
Проблема в том, что это вообще не оживляет и показывает излучатель в его окончательном положении. У меня сложилось впечатление, что, как только вы добавите анимацию к слою, вы должны изменить фактическую модель позади нее в ее конечное положение, чтобы после завершения анимации модель находилась в своем конечном состоянии; то есть, чтобы анимация не "вернулась назад" в исходное положение.
Я попытался поместить последние две строки в animation.completion
блок, и это действительно оживляет, как и ожидалось. Однако, когда анимация заканчивается, некоторые частицы периодически испускаются в исходном положении излучателя. Если вы загружаете систему (например, прокручиваете таблицу во время воспроизведения анимации), это происходит чаще.
Другое решение, о котором я думал, это не двигать emitterPosition
на все, но просто переместите CAEmitterLayer
сам, хотя я еще не пробовал.
Заранее благодарим за любую помощь, которую вы можете предоставить.
1 ответ
Возможно emitterPosition.x
не является допустимым ключевым путем для анимации. Попробуйте использовать emitterPosition
вместо этого (и поэтому вы должны будете предоставить значения CGPoint, обернутые в NSValue).
Я только что попробовал это на моей собственной машине, и она отлично работает:
CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"emitterPosition"];
ba.fromValue = [NSValue valueWithCGPoint:CGPointMake(30,100)];
ba.toValue = [NSValue valueWithCGPoint:CGPointMake(200,100)];
ba.duration = 6;
ba.autoreverses = YES;
ba.repeatCount = HUGE_VALF;
[emit addAnimation:ba forKey:nil];
Другие вещи, чтобы думать о:
Обычно вы можете использовать ноль в качестве ключа в
addAnimation:forKey:
, если вам не понадобится найти эту анимацию позже (например, чтобы удалить или переопределить ее каким-либо образом). Ключевой путь - важная вещь.настройка
removedOnCompletion
НЕТ почти всегда неверно и обычно является последним прибежищем негодяя (т.е. из-за непонимания того, как работает анимация).Если, как вы говорите, настройка
_emitterLayer.emitterPosition = newEmitterPosition
внутри блока завершения происходит анимация, тогда когда вы вообще используете CABasicAnimation? Почему бы просто не позвонить UIViewanimate...
и установить emitterPosition в блоке анимации? Если это сработает, это убьет двух зайцев одним движением, сдвинув позицию и оживив ее тоже.