Исходные частицы из CAEmitterLayer не запускаются в emitterPosition

Моя цель - сделать взрывоподобную анимацию, в которой за короткое время испускается много частиц. Моя проблема в том, что CAEmitterLayer, когда он начинает излучать, добавляет "будущие" частицы, чтобы они выглядели так, как будто анимация уже запущена.

Как я могу отключить или обойти это? Когда я увеличиваю birthRate, я хочу, чтобы частицы начинали появляться только из emitterPosition, а не во всех точках в течение предполагаемого времени жизни CAEmitterCell. Любая помощь приветствуется.

#import "EmitterView.h"

@interface EmitterView ()

@property CAEmitterLayer* emitter;

@end

@implementation EmitterView

- (void) awakeFromNib {
    [super awakeFromNib];
    self.emitter = (CAEmitterLayer*)self.layer;

    CAEmitterCell* snowflake = [CAEmitterCell emitterCell];
    snowflake.contents = (id)[[UIImage imageNamed: @"snowflake"] CGImage];
    snowflake.lifetime = 3;
    snowflake.birthRate = 1;
    snowflake.velocity = 50;
    snowflake.emissionRange = 3.1415;

    self.emitter.birthRate = 0;
    self.emitter.emitterCells = [NSArray arrayWithObject: snowflake];
    self.emitter.emitterPosition = CGPointMake(100, 100);
    self.emitter.emitterSize = CGSizeMake(0, 0);
    self.emitter.emitterShape = kCAEmitterLayerPoint;
}

+ (Class) layerClass {
    return [CAEmitterLayer class];
}

- (void) burst {
    self.emitter.birthRate = 10;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        self.emitter.birthRate = 0;
    });
}

@end

1 ответ

Решение

Это поведение фактически изменилось с выпуском iOS 7 и, видимо, с тех пор не вернулось. Раньше он вел себя так, как вы ожидали еще до iOS 7, но либо Apple представила ошибку, вызвавшую это, либо они решили изменить поведение, не сказав никому.

28 августа 2013 года я подал ошибку для этой конкретной проблемы, которая была закрыта как дубликат другого отчета об ошибке для той же проблемы. Репортер ошибок Apple сообщает, что другая ошибка все еще открыта, что означает, что Apple еще не устраняла ее, несмотря на то, что о ней позаботились более полутора лет.

Я рекомендую заполнить свой собственный отчет об ошибках в Apple, предоставив им простое приложение, демонстрирующее поведение, и, возможно, привлечение к нему нового внимания поможет им что-то с этим сделать.

РЕДАКТИРОВАТЬ:

Немного изучив проблему, я обнаружил, что решение заключается в добавлении этой строки:

self.emitter.beginTime = CACurrentMediaTime();

Важно знать, что CAEmitterLayer это подкласс CALayer, что соответствует CAMediaTiming протокол. Почему весь этот факт лучше не задокументирован, мне не под силу.

Обратите внимание, что вы, вероятно, хотите позвонить с вашего - (void)burst метод, но если вы вызываете его снова в течение короткого периода времени, пока предыдущие частицы все еще существуют, вы можете увидеть какое-то странное поведение из-за сброса beginTime,

Другие вопросы по тегам