Подтвердить что ты не робот

IOS 7 CAEmitterLayer нерегулярно порождает частицы

Странная проблема. Кажется, я не могу решить, где только на iOS 7, CAEmitterLayer неправильно порождает частицы на экране, когда рождаемость первоначально установлена ​​на ненулевое значение. Он как бы вычисляет состояние, в котором слой будет в будущем.

// Create black image particle
CGRect rect = CGRectMake(0, 0, 20, 20);
UIGraphicsBeginImageContext(rect.size);
CGContextFillRect(UIGraphicsGetCurrentContext(), rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// Create cell
CAEmitterCell *cell = [CAEmitterCell emitterCell];
cell.contents = (__bridge id)img.CGImage;
cell.birthRate = 100.0;
cell.lifetime = 10.0;
cell.velocity = 100.0;

// Create emitter with particles emitting from a line on the
// bottom of the screen
CAEmitterLayer *emitter = [CAEmitterLayer layer];
emitter.emitterShape = kCAEmitterLayerLine;
emitter.emitterSize = CGSizeMake(self.view.bounds.size.width,0);
emitter.emitterPosition = CGPointMake(self.view.bounds.size.width/2,
                                      self.view.bounds.size.height);
emitter.emitterCells = @[cell];

[self.view.layer addSublayer:emitter];

Я видел на DevForums одно сообщение, в котором несколько человек упомянули, что у них были подобные проблемы с iOS 7 и CAEmitterLayer, но никто не имел никаких идей, как его исправить. Теперь, когда iOS 7 больше не бета-версия, я решил, что я должен спросить здесь и посмотреть, может ли кто-нибудь ее взломать. Я действительно надеюсь, что это не просто ошибка, которую мы должны ждать, когда 7.0.1 или 7.1 будут исправлены. Любые идеи будут высоко оценены. Спасибо!

4b9b3361

Ответ 1

ДА!

Я потратил часы на эту проблему самостоятельно.

Чтобы получить тот же вид анимации birthRate, который у нас был, прежде чем мы используем пару стратегий.

Во-первых, если вы хотите, чтобы слой выглядел так, как он начинает излучать при добавлении в представление, вам нужно помнить, что CAEmitterLayer является подклассом CALayer, который соответствует протоколу CAMediaTiming. Мы должны установить, чтобы весь слой излучателя начинался в текущий момент:

emitter.beginTime = CACurrentMediaTime();
[self.view.layer addSublayer:emitter];

Как будто он вычисляет состояние, в котором будет слой в будущем.

Вы были устрашающе близки, но на самом деле это то, что эмитент начинал в прошлом.

Во-вторых, для анимации между рождаемостью 0 и n с тем эффектом, которым мы располагаем, прежде чем мы можем манипулировать свойством lifetime:

if (shouldBeEmitting){
    emitter.lifetime = 1.0;
}
else{
    emitter.lifetime = 0;
}

Обратите внимание, что я устанавливаю lifetime на сам слой эмиттера. Это связано с тем, что при испускании версии излучателя ячейки этого свойства умножается на значение в слое эмиттера. Установка lifetime уровня излучателя устанавливает кратное значение lifetime всех ваших ячеек-эмиттеров, что позволяет легко и просто отключать их.

Ответ 2

Для меня проблема с моим CAEmitterLayer при переходе на iOS7 была следующей:

В настройке iOS7 продолжительность CAEmitterLayerCell приводила к тому, что частица вообще не показывалась!

Единственное, что мне пришлось изменить, это удалить cell.duration = XXX, после чего мои частицы снова начали появляться. Я собираюсь съесть Apple над этим неожиданным, необъяснимым хлопотом.