У меня проблема с переводом приложения iPhone в фоновый режим, нажав кнопку выхода, а затем снова запустив его, нажав значок запуска на главном экране: представление приложения возвращается в исходное состояние, как я хочу, но дочто он на короткое время мигает на экране ранее, неправильное состояние просмотра.
Фон
Мой основной вид состоит в основном из последовательности связанных вызовов UIAnimateWithDuration.Поведение, которое я хочу всякий раз, когда происходит какое-либо прерывание, состоит в том, чтобы вернуть анимацию в ее начальное состояние (если анимация не завершилась и приложение не перешло в статическую финальную фазу), и запускать ее оттуда всякий раз, когда приложение возвращается в активное и видимое состояние..
После изучения предмета я узнал, что мне нужен два типа кода обработки прерываний, чтобы обеспечить хороший ux: «мгновенный» и «плавный».У меня есть метод resetAnimation, который мгновенно сбрасывает свойства представления в начальное состояние, и метод pauseAnimation, который быстро анимирует в то же состояние, с дополнительной меткой, указывающей на «пауза» исчезновения в верхней части представления.
Двойной щелчок по кнопке выхода
Причиной этого является вариант использования «двойного щелчка по кнопке выхода», который фактически не скрывает ваш вид и не переводит вас в фоновое состояние, он просто прокручиваетсянемного, чтобы показать меню многозадачности внизу.Итак, мгновенный сброс состояния просмотра в этом случае выглядел очень уродливо.Анимированный переход и информирование пользователя о том, что вы приостановлены, казались лучшей идеей.
Этот случай работает хорошо и плавно, реализуя метод делегата applicationWillResignActive в моем делегате приложения и вызывая оттуда pauseAnimation.Я обрабатываю возврат из этого меню многозадачности, реализуя метод делегата applicationDidBecomeActive и вызывая оттуда мой метод resumeAnimation, который затухает в метке «приостановлено», если она там есть, и запускает последовательность анимации из исходного состояния.
Thisвсе работает отлично, нигде не мерцая.
Посещение флипсайда
Мое приложение построено на шаблоне "утилиты" Xcode, поэтому у него есть перевернутый вид для отображения информации / настроек,Я управляю посещением обратной стороны и возвращаюсь к основному виду, реализуя эти два метода делегата в моем контроллере основного вида:
Я вызываю метод resetAnimation в методе viewDidDisappear и возобновляю анимацию в 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
}
}