No momento exato em que o iOS tira o instantâneo da visualização ao entrar em segundo plano?

Tenho um problema ao colocar meu aplicativo para iPhone em segundo plano pressionando o botão sair e, em seguida, reiniciando tocando no ícone de inicialização na tela inicial: a visualização do aplicativo retorna ao seu estado inicial como eu quero, mas antes disso pisca brevemente o estado de exibição anterior errad

Fund

Minha visão principal consiste basicamente em uma sequência de chamadas UIAnimateWithDuration interligadas. O comportamento que desejo sempre que ocorre uma interrupção é redefinir a animação para seu estado inicial (a menos que as animações tenham terminado e o aplicativo tenha entrado na fase final estática) e recomeçar a partir daí sempre que o aplicativo retornar ao estado ativo e visível .

Depois de estudar o assunto, aprendi que preciso de dois tipos de código de manipulação de interrupções para fornecer uma boa experiência de usuário: "instantâneo" e "suave". Eu tenho o método resetAnimation que redefine as propriedades da exibição para o estado inicial instantaneamente e o método pauseAnimation que anima rapidamente para o mesmo estado, com um rótulo adicional indicando "pausado" aparecendo na parte superior da exibição.

Clique duas vezes no botão sair

A razão para isso é o caso de uso "botão de saída com duplo clique", que na verdade não oculta sua visualização ou coloca você no estado de segundo plano, apenas rola um pouco para cima para mostrar o menu multitarefa na parte inferior. Portanto, redefinir o estado da visualização instantaneamente neste caso parecia muito feio. A transição animada e dizer ao usuário que você fez uma pausa pareceu uma ideia melhor.

Este caso funciona bem e sem problemas implementando o método delegado applicationWillResignActive no meu App Delegate e chamando pauseAnimation a partir daí. Lido com o retorno desse menu multitarefa implementando o método delegado applicationDidBecomeActive e chamando a partir daí meu método resumeAnimation, que diminui o rótulo "pausado", se houver, e inicia minha sequência de animação a partir do estado inicial.

Isso tudo funciona bem, sem oscilações em qualquer luga

Visiting flipside

@My app foi construído sobre o modelo "utilitário" do Xcode, por isso tem uma visualização do outro lado para mostrar informações / configurações. Eu ligo para visitar o outro lado e retornar à visualização principal implementando esses dois métodos delegados no meu controlador de visualização principal:

(void) viewDidDisappear: (BOOL) animado

(vazio) viewDidAppear: (BOOL) animado

Ligo meu resetAnimation no método viewDidDisappear e resumeAnimation em viewDidAppear. Tudo isso funciona bem, a visualização principal é o seu estado inicial desde o início da transição para o estado visível - sem flashes inesperados de estados de animação incorretos. Mas

Pressione o botão de saída e reinicie no ícone do meu aplicativo (a parte do buggy!)

É aqui que o problema começa. Quando pressiono o botão sair uma vez e meu aplicativo inicia sua transição para segundo plano, duas coisas acontecem. Primeiro, applicationWillResignActive também é chamado aqui, então meu método pauseAnimation é iniciado também. Não seria necessário, pois a transição não precisa ser suave aqui - a visualização fica estática e diminui o zoom para revelar a tela inicial - mas o que você pode fazer? Bem, também não faria mal se eu pudesse chamar resetAnimation antes do momento exato em que o sistema tira o instantâneo da visualizaçã

De qualquer forma, segundo, applicationDidEnterBackground no App Delegate é chamado. Tentei chamar resetAnimation a partir daí para que a exibição estivesse no estado correto quando o aplicativo retornar, mas isso não parece funcionar. Parece que o "instantâneo" já foi tirado e, portanto, quando toco no ícone de inicialização do aplicativo e relanço, o estado de exibição incorreto pisca brevemente na tela antes que o estado inicial correto seja exibido. Depois disso, tudo funciona bem, as animações acontecem como deveriam, mas aquela piscada feia naquele momento de relançamento não desaparece, não importa o que eu tent

Fundamentalmente, o que estou procurando é, em que momento exato o sistema tira esse instantâneo? E, consequentemente, qual seria o método delegado ou o manipulador de notificação correto para preparar minha exibição para tirar a "foto de lembrança"?

PS. Depois, há o default.png, que parece não aparecer apenas no primeiro lançamento, mas também sempre que o processador está com dificuldades ou está retornando ao aplicativo atrasado brevemente por algum outro motivo. É um pouco feio, especialmente se você estiver retornando à sua exibição do outro lado, totalmente diferente da sua exibição padrão. Mas esse é um recurso essencial do iOS, acho que eu nem deveria tentar descobrir ou controlar esse:)

Edit: desde que as pessoas estavam pedindo o código real, e meu aplicativo já foi lançado depois de fazer esta pergunta, vou postar alguns aqui. (O aplicativo se chama Sweetest Kid, e se você quiser ver como ele realmente funciona, está aqui:http: //itunes.apple.com/app/sweetest-kid/id476637106? mt = 8 )

Aqui está o meu método pauseAnimation - resetAnimation é quase idêntico, exceto que sua chamada de animação tem duração e atraso zero e não mostra o rótulo 'Pausado'. Uma razão pela qual estou usando o UIAnimation para redefinir os valores, em vez de apenas atribuir os novos valores, é que, por algum motivo, as animações simplesmente não param se eu não usar o UIAnimation. Enfim, aqui está o método pauseAnimation:

    - (void)pauseAnimation {
    if (currentAnimationPhase < 6 || currentAnimationPhase == 255) { 
            // 6 means finished, 255 is a short initial animation only showing at first launch
        self.paused = YES;
        [UIView animateWithDuration:0.3
                              delay:0 
                            options:UIViewAnimationOptionAllowUserInteraction |
         UIViewAnimationOptionBeginFromCurrentState |
         UIViewAnimationOptionCurveEaseInOut |
         UIViewAnimationOptionOverrideInheritedCurve |
         UIViewAnimationOptionOverrideInheritedDuration
                         animations:^{
                             pausedView.alpha = 1.0;
                             cameraImageView.alpha = 0;
                             mirrorGlowView.alpha = 0;
                             infoButton.alpha = 1.0;
                             chantView.alpha = 0; 
                             verseOneLabel.alpha = 1.0;
                             verseTwoLabel.alpha = 0; 
                             verseThreeLabel.alpha = 0;
                             shine1View.alpha = stars1View.alpha = stars2View.alpha = 0;
                             shine1View.transform = CGAffineTransformIdentity;
                             stars1View.transform = CGAffineTransformIdentity;
                             stars2View.transform = CGAffineTransformIdentity;
                             finishedMenuView.alpha = 0;
                             preparingMagicView.alpha = 0;}
                         completion:^(BOOL finished){
                             pausedView.alpha = 1.0;
                             cameraImageView.alpha = 0;
                             mirrorGlowView.alpha = 0;
                             infoButton.alpha = 1.0;
                             chantView.alpha = 0; 
                             verseOneLabel.alpha = 1.0;
                             verseTwoLabel.alpha = 0; 
                             verseThreeLabel.alpha = 0;
                             shine1View.alpha = stars1View.alpha = stars2View.alpha = 0;
                             shine1View.transform = CGAffineTransformIdentity;
                             stars1View.transform = CGAffineTransformIdentity;
                             stars2View.transform = CGAffineTransformIdentity;
                             finishedMenuView.alpha = 0;
                             preparingMagicView.alpha = 0;
                         }];
        askTheMirrorButton.enabled = YES; 
        againButton.enabled = NO;
        shareOnFacebookButton.enabled = NO;
        emailButton.enabled = NO;
        saveButton.enabled = NO;
        currentAnimationPhase = 0;
        [[cameraImageView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)]; // To remove the video preview layer
    }
}

questionAnswers(5)

yourAnswerToTheQuestion