Точный момент, когда iOS делает снимок представления при входе в фоновый режим?

У меня проблема при установке приложения для iPhone в фоновый режим, нажав кнопку выхода, а затем перезапустив его, нажав значок запуска на главном экране: представление приложения возвращается в исходное состояние, как я хочу, но перед этим на экране на короткое время мигает предыдущее неправильное состояние просмотра.

Предпосылки

Мое основное представление состоит в основном из последовательности взаимосвязанных вызовов UIAnimateWithDuration.Поведение, которое я хочу всякий раз, когда происходит какое-либо прерывание, - это сбросить анимацию в исходное состояние (если анимация не завершена и приложение не перешло в статическую финальную фазу) и начинать с этого момента всякий раз, когда приложение возвращается в активное и видимое состояние. .

После изучения предмета я узнал, что мне нужны два типа кода обработки прерывания, чтобы обеспечить хорошее взаимодействие: «мгновенный» и «плавный». У меня есть метод resetAnimation, который мгновенно сбрасывает свойства представления в исходное состояние, и метод pauseAnimation, который быстро анимирует то же состояние, с дополнительной меткой, указывающей, что «приостановлено» постепенно исчезает в верхней части представления.

Двойное нажатие кнопки выхода

Причиной этого является вариант использования «двойного нажатия кнопки выхода», который на самом деле не скрывает ваш вид и не переводит вас в фоновое состояние, он просто немного прокручивается, чтобы показать многозадачность меню внизу. Таким образом, мгновенный сброс состояния просмотра в этом случае выглядел очень некрасиво. Анимированный переход и сообщение пользователю о том, что вы приостановили, казались лучшей идеей.

Этот случай работает красиво и плавно, реализуя метод делегата applicationWillResignActive в моем делегате приложения и вызывая оттуда pauseAnimation. Я обрабатываю возврат из этого многозадачного меню, реализуя метод делегата applicationDidBecomeActive и вызывая оттуда мой метод resumeAnimation, который затемняет метку «приостановлено», если она есть, и запускает последовательность анимации из начального состояния.

Все работает нормально, нигде не мерцает.

Посещение обратной стороны

Мое приложение построено на «служебном» шаблоне Xcode, поэтому у него есть обратная сторона для отображения информации / настроек. Я обрабатываю посещение обратной стороны и возвращаюсь к основному представлению, реализуя эти два метода делегата в моем основном контроллере представления:

  • (void) viewDidDisappear: (BOOL) animated

  • (void) viewDidAppear: (BOOL) animated

Я вызываю свой resetAnimation в методе viewDidDisappear и resumeAnimation в viewDidAppear. Все это работает нормально, основной вид - это его начальное состояние с самого начала перехода в видимое состояние - никаких неожиданных миганий неправильных состояний анимации чего-либо. Но:

Нажатие кнопки выхода и перезапуск из моего значка приложения (часть с ошибками!)

Вот тут и начинаются проблемы. Когда я нажимаю кнопку выхода один раз, и мое приложение начинает переход в фоновый режим, происходят две вещи. Во-первых, здесь также вызывается applicationWillResignActive, поэтому также запускается мой метод pauseAnimation. В этом нет необходимости, поскольку переход не должен быть здесь плавным - вид просто становится статичным и «уменьшается», чтобы открыть главный экран - но что вы можете сделать? Что ж, это тоже не повредило бы, если бы я мог просто вызвать resetAnimation до того момента, когда система сделает снимок вида.

В любом случае, во-вторых, вызывается applicationDidEnterBackground в делегате приложения. Я попытался вызвать resetAnimation оттуда, чтобы представление было в правильном состоянии, когда приложение вернется, но это, похоже, не работает.Кажется, что «моментальный снимок» уже был сделан, поэтому, когда я нажимаю значок запуска приложения и перезапускаю его, неправильное состояние просмотра на короткое время мигает на экране, прежде чем отображается правильное начальное состояние. После этого все работает нормально, анимация идет так, как должна, но это уродливое мерцание в момент перезапуска не исчезнет, ​​что бы я ни пытался.

По сути, меня интересует, в какой именно момент система делает этот снимок? И следовательно,Какой будет правильный метод делегирования или обработчик уведомлений, чтобы подготовить мое представление к съемке «сувенирной фотографии»?

PS. Затем есть файл default.png, который, похоже, отображается не только при первом запуске, но и всякий раз, когда у процессора возникают проблемы или возврат в приложение ненадолго задерживается по какой-то другой причине. Это немного некрасиво, особенно если вы возвращаетесь к своему обратному виду, которое полностью отличается от вашего представления по умолчанию. Но это такая основная функция iOS, я предполагаю, что мне даже не следует пытаться выяснить или контролировать ее :)


Изменить: поскольку люди запрашивали реальный код, и мое приложение уже было выпущено после запроса этот вопрос я опубликую здесь. (Приложение называется Sweetest Kid, и если вы хотите увидеть, как оно работает на самом деле, оно здесь: http://itunes.apple.com/app/sweetest-kid/id476637106?mt=8 )

Вот мой метод pauseAnimation - resetAnimation почти идентичен, за исключением того, что его вызов анимации имеет нулевую длительность и задержку, и он не показывает метку «Приостановлено». Одна из причин, по которой я использую UIAnimation для сброса значений вместо того, чтобы просто назначать новые значения, заключается в том, что по какой-то причине анимация просто не останавливалась, если я не использовал UIAnimation. В любом случае, вот метод 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
    }
}

21
задан Samuli Viitasaari 29 November 2011 в 08:08
поделиться