2013-05-25 13 views
7

Chciałbym stworzyć efekt cząsteczkowy, który emituje tylko wtedy, gdy użytkownik dotknie ekranu, ale nie mogę zmienić właściwości birthRate CAEmitterCell, gdy zostanie ustawiona wartość niezerowa.CAEmitterCell nie respektuje zmiany parametru birthRate

Mam podklasę UIView, która ustawia moje CAEmitterLayer i moje CAEmitterCell dokładnie tak, jak chcę. Ja definiowania dwie właściwości w tej klasie:

@property (strong, nonatomic) CAEmitterLayer *emitterLayer; 
@property (strong, nonatomic) CAEmitterCell *emitterCell; 

Wtedy, moim zdaniem regulatora, ja dotyka śledzenia, ustawienie pozycji emitterLayer i emitterCell urodzeń:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGPoint tappedPt = [touch locationInView:touch.view]; 
    NSLog(@"began x:%f y:%f",tappedPt.x, tappedPt.y); 
    emitterView.emitterCell.birthRate = 42; 
    emitterView.emitterLayer.emitterPosition = tappedPt; 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGPoint tappedPt = [touch locationInView:touch.view]; 
    NSLog(@"moved x:%f y:%f",tappedPt.x, tappedPt.y); 
    emitterView.emitterLayer.emitterPosition = tappedPt; 
} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 
    NSLog(@"ending %f", emitterView.emitterCell.birthRate); 
    emitterView.emitterCell.birthRate = 0.00; 
    NSLog(@"ended %f", emitterView.emitterCell.birthRate); 
} 

Sprawozdania dziennika emitterView.emitterCell.birthRate zmienia:

began x:402.000000 y:398.500000 
ending 42.000000 
ended 0.000000 

kiedy dotknąć ekranu, rozpoczyna emiter zgodnie z oczekiwaniami, warstwa następuje w dotyku, ale kiedy zakończyć dotyku, emitować ter cell szczęśliwie emituje dowolną wartość ustawioną początkowo (wartość ustawiona w touchesBegan). Cokolwiek robię, nie mogę wydawać się w stanie zmienić wartości narodzin, gdy tylko ustawi się wartość niezerową. Dziennik informuje, że wartości są ustawione prawidłowo, ale emitent emituje sygnał.

Jednakże, jeśli mogę zmienić metodę touchesEnded aby zmienić położenie warstwy, po tym, jak ustawić wskaźnik urodzeń na emitterCell wtedy wszystko działa zgodnie z oczekiwaniami:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 
    UITouch *touch = [touches anyObject]; 
    CGPoint tappedPt = [touch locationInView:touch.view]; 
    NSLog(@"began x:%f y:%f",tappedPt.x, tappedPt.y); 

    NSLog(@"ending %f", emitterView.emitterCell.birthRate); 
    emitterView.emitterCell.birthRate = 0.0; 
    NSLog(@"ended %f", emitterView.emitterCell.birthRate); 
    emitterView.emitterLayer.emitterPosition = tappedPt; 
} 

Może ktoś proszę wyjaśnić dlaczego?

+0

czy kiedykolwiek tego dowiedzieć? – scott

Odpowiedz

6

nie wiem dlaczegoto zachowuje się nieco dziwne, ale okazało się, że przy użyciu klucza wartość kodowania rozwiązuje ten problem i komórka przestaje emitujące:

Zakładając, że CAEmitterLayer jest „yourEmitterLayer” i masz CAEmitterCell o nazwie „yourEmitterCell”, to zatrzymać emisję jeśli umieszczony wewnątrz touchesEnded:

[yourEmitterLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"emitterCells.yourEmitterCell.birthRate"]; 
+0

dwa pytania: 1) birthRate jest zmiennoprzecinkowe, przypisujesz int. 2) czy manipulacja emiterem musi zawsze zaczynać się od emiter? Mam na myśli, w tym przypadku wywołujesz emiter i przekazujesz ścieżkę 'emitterCells.yourEmitterCell.birthRate', ale przypuśćmy, że mam odniesienie do samego emiteraCell. Czy mogę po prostu zrobić "[self.emiterCell .... forKeyPath: @" birthRate "]'? – SpaceDog

+0

Chciałbym również znać odpowiedź na pytanie powyższego komentatora –

+0

Aby pracować nad tym kodem, należy ustawić właściwość name dla każdego emittercells self.yourEmitterCell.name = @ "yourEmitterCell", – Anees

2

aby zatrzymać emitujące cząstki trzeba ustawić birthRate własnością CAEmitterLayer przykład do 0, mimo że początkowo ustawiona naInstancja... Nie wiem dlaczego, ale działa.

Swift 3 Przykład:

func emitParticles() { 
    let particlesEmitter = CAEmitterLayer() 
    particlesEmitter.emitterPosition = center 
    particlesEmitter.emitterShape = kCAEmitterLayerCircle 
    particlesEmitter.emitterSize = CGSize(width: 50, height: 50) 
    particlesEmitter.renderMode = kCAEmitterLayerAdditive 

    let cell = CAEmitterCell() 
    cell.birthRate = 15 
    cell.lifetime = 1.0 
    cell.color = bubble.color.cgColor 
    cell.velocity = 150 
    cell.velocityRange = 50 
    cell.emissionRange = .pi 
    cell.scale = 0.1 
    cell.scaleSpeed = -0.1 

    cell.contents = UIImage(named: "particle")?.cgImage 
    particlesEmitter.emitterCells = [cell] 

    layer.addSublayer(particlesEmitter) 

    DispatchQueue.main.asyncAfter(deadline: .now() + 1) { 
     particlesEmitter.birthRate = 0 
    } 
} 
Powiązane problemy