2013-04-03 31 views
6

Zaimplementowałam klasę LoadingLayer, która ma kilka elementów animujących (dokładnie 2), które są animowane przez CABasicAnimation. Teraz ten widok ekranu ładowania pojawia się w całej aplikacji. Czy ukrycie widoku zatrzymuje wszystkie animacje? Albo pozwól mi powtórzyć: Czy jest dużo pamięci, o którą muszę się martwić, czy może to spowodować opóźnienia? Próbowałem użyć metod , ale spowodowały one pewne problemy z powodu wielowątkowości w mojej aplikacji. Czy w związku z tym dobrze jest ukrywać i wyświetlać ekran ładowania z ciągle pojawiającymi się animacjami?Przerwać i wznowić CABasicAnimation do ładowania ekranu?

Odpowiedz

9

https://developer.apple.com/library/content/qa/qa1673/_index.html

-(void)pauseLayer:(CALayer*)layer 
{ 
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; 
    layer.speed = 0.0; 
    layer.timeOffset = pausedTime; 
} 

-(void)resumeLayer:(CALayer*)layer 
{ 
    CFTimeInterval pausedTime = [layer timeOffset]; 
    layer.speed = 1.0; 
    layer.timeOffset = 0.0; 
    layer.beginTime = 0.0; 
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; 
    layer.beginTime = timeSincePause; 
} 
+0

miałem dość podobny wdrożenie, ale działa, dziękuję! –

+0

Okay, nie, faktycznie miałem dokładnie taką samą implementację. Ale teraz wiem, dlaczego przestała działać od czasu do czasu. Za każdym razem, gdy aplikacja przechodzi w tło i ponownie ją uruchomię, animacje nie zostaną wznowione. Jakiś pomysł, co może być przyczyną tego? –

+1

spróbuj wyczyścić animacje i wczytać je na didBeomceActive – Nico

0

Jeśli widok jest ukryty (niewidoczny lub nie w interfejsie w ogóle), to nie jest część drzewa renderowania.

Ale dlaczego nie po prostu zatrzymać animację, gdy kontroler widoku, w którego widoku osadzona jest ta warstwa, opuszcza interfejs (viewDidDisappear)? Po prostu powiedz warstwę do removeAllAnimations. Następnie, jeśli chcesz, stwórz animację ponownie w viewWillAppear?

2

Oto szybka wersja 3 z odpowiedzią Nico's.

Nadzieja pomaga!

fileprivate func pauseLayer(layer: CALayer) { 
    let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil) 
    layer.speed = 0.0 
    layer.timeOffset = pausedTime 
} 

fileprivate func resumeLayer(layer: CALayer) { 
    let pausedTime = layer.timeOffset 
    layer.speed = 1.0 
    layer.timeOffset = 0.0 
    layer.beginTime = 0.0 
    let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime 
    layer.beginTime = timeSincePause 
} 
0

Rozszerzanie Nico „s odpowiedzi na modyfikację prędkości do każdej zmiennej:

extension CALayer { 
    func udpate(speed newSpeed: Float) { 
     let newSpeed = newSpeed == 0 ? 1e-6 : newSpeed 
     let triggerTime = self.convertTime(CACurrentMediaTime(), from: nil) 
     let offset = self.timeOffset 
     let begin = self.beginTime 
     let speed = self.speed 
     self.beginTime = (triggerTime - offset)/Double(speed) + begin 
     self.timeOffset = triggerTime 
     self.speed = newSpeed 
    } 
} 

użyć tego podejścia, jeśli jesteś gotów do zmiany prędkości animacji warstwy interaktywnie. Jeśli chcesz całkowicie wyłączyć warstwę, należy użyć odpowiedź Nico, chociaż przy użyciu tej metody z speed=0.0 rzeczywiście zajmuje około 11 dni dla animacje do końca, aw 1 godzinę animacji będzie postępu o 0.0036