Почему мое приложение не возвращается к подробному виду после восстановления?

Мое приложение имеет простую организацию, которую я настроил в раскадровке Interface Builder (не в коде). Есть Контроллер Навигационного Представления, у которого его Контроллер Root View установлен в мой Основной Контроллер Представления. Мое главное представление содержит таблицу, в которой ячейки переходят в контроллер подробного представления.

Когда я приостанавливаю приложение, просматривая подробный вид, а затем возобновляю его, я возвращаюсь в основной вид, а не в подробный вид. Почему это может быть?

Подробности:

Я установил идентификаторы восстановления в Интерфейсном Разработчике для Контроллера Представления Навигации, Контроллера Главного Представления и Контроллера Детального Представления. Я также попытался добавить идентификатор восстановления в табличное представление и заставить контроллер основного представления реализовать UIDataSourceModelAssociation.

Мое приложение возвращает YES из shouldRestoreApplicationState, и оба основных вида и подробный вид имеют методы encode / decodeRestorableStateWithCoder.

Я тестирую приостановку / возобновление с помощью симулятора: я запускаю приложение, перехожу к подробному виду, нажимаю кнопку "Домой" и затем нажимаю кнопку "Стоп" в XCode. Чтобы возобновить, я снова запускаю приложение из XCode.

Я вижу следующие звонки в режиме ожидания:

AppDelegate shouldSaveApplicationState
MainViewController encodeRestorableStateWithCoder
DetailViewController encodeRestorableStateWithCoder

И в резюме:

AppDelegate shouldRestoreApplicationState
AppDelegate viewControllerWithRestorationIdentifierPath Navigation
AppDelegate viewControllerWithRestorationIdentifierPath Navigation/MainView
MainViewController viewDidLoad
AppDelegate viewControllerWithRestorationIdentifierPath Navigation/DetailView
MainViewController decodeRestorableStateWithCoder

Помимо того, что восстанавливается неправильный вид, есть еще кое-что странное: почему путь идентификатора восстановления для подробного вида "Navigation/DetailView", а не "Navigation/MainView/DetailView"? Нет прямой связи между контроллером навигационного представления и контроллером подробного просмотра. Их единственное соединение в Интерфейсном Разработчике через переход от Главного Представления.

Я что-то неправильно настроил?

Я попытался назначить класс восстановления в подробном представлении. Когда этот код восстановления вызывается, он терпит неудачу, потому что UIStateRestorationViewControllerStoryboardKey не установлен в кодере.

Вот игрушечная версия моего проекта, которая повторяет проблему: https://github.com/WanderingStar/RestorationTest

Я пытаюсь сделать это с версией XCode 5.0 (5A1413) и iOS Simulator Version 7.0 (463.9.4), на случай, если они актуальны.

2 ответа

Решение

Ответ оказался простым: я не звонил

[super encodeRestorableStateWithCoder:coder];

в encodeRestorableStateWithCoder: метод кодера в моих контроллерах вида (и делающий то же самое в декодировании...).

Это руководство помогло мне пройти каждый шаг процесса и выяснить, где я ошибся: http://useyourloaf.com/blog/2013/05/21/state-preservation-and-restoration.html

Также оказывается, что "Navigation/DetailView" - это то, что ожидается. Контроллер навигационных представлений восстанавливает все представления в своем стеке и затем помещает их обратно в стек, а не каждое представление восстанавливает более поздние представления в стеке.

В Руководстве по программированию приложения для iOS, раздел "Сохранение и восстановление состояния", есть удобный контрольный список того, что нужно сделать, чтобы восстановить работу.

После просмотра вашего кода кажется, что вы забыли шаг 3, Назначить классы восстановления. У ваших классов нет этих свойств, а вы не реализовали viewControllerWithRestorationIdentifierPath в приложении делегат.

Назначьте классы восстановления соответствующим контроллерам представления. (Если вы этого не сделаете, вашему приложению будет предложено предоставить соответствующий контроллер представления во время восстановления.) См. "Восстановление ваших контроллеров представления во время запуска".

Я посмотрел на ваш образец, и приложение WillFinishLaunching отсутствует [self.window makeKeyAndVisible] что является требованием для государственного восстановления. Это приведет к тому, что контроллер сплита немедленно рухнет, а затем он будет восстановлен правильно.

Существует проблема, заключающаяся в том, что если он был сохранен в альбомной ориентации, т. Е. В режиме раздельного разделения, а затем запущен в портретной ориентации, то путь будет неправильным. В этом случае при запуске он сначала свернется, чтобы соответствовать текущему экрану, затем начнет восстановление и сначала разделится, а после завершения восстановления снова свернется, чтобы соответствовать текущему экрану. В течение этого времени вам нужно реализовать viewControllerWithRestorationIdentifierPath и использовать последнюю строку в пути, чтобы идентифицировать контроллер и вернуть его после того, как он захватил то, из чего изначально была создана раскадровка, в которой будет завершен запуск. Затем вы можете очистить эти свойства в didFinish.

Другие вопросы по тегам