Восстановление состояния в панели вкладок и в приложении Navigation Controller

Цель: я пытаюсь восстановить состояние приложения на основе контроллера вкладок (с контроллерами навигации на каждой вкладке).

Проблема: При повторном запуске выбранная вкладка, кажется, восстанавливается, как и ожидалось, но иерархия навигации внутри указанной вкладки - нет.

Разработка:

  1. Я впервые начал с шаблона проекта "Приложение на основе вкладок".
  2. Затем я добавил идентификаторы восстановления для обоих дочерних контроллеров представления и контроллера панели вкладок.
  3. В приложении делегат я реализовал application(_:shouldSaveApplicationState:) а также application(_:shouldRestoreApplicationState:),

Затем я запускаю приложение, переключаюсь на вторую (правую) вкладку, нажимаю home, завершаю работу. o перезапуск, отображается правая вкладка (как и ожидалось). Все идет нормально.

  1. Затем я перехожу к раскадровке и встраиваю оба дочерних контроллера представления в соответствующие контроллеры навигации, и назначаю им идентификаторы восстановления.

Я запускаю приложение, и восстановление все еще работает. Все еще хорош.

  1. Затем я добавляю "детальный" вид контроллера; его класс является пользовательским подклассом UIViewController к раскадровке со свойствами для настройки содержимого метки отладки и цвета фона его представления.

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

  3. На каждом из контроллеров вида сверху prepareForSegue(_:sender:) Метод, я настраиваю контроллер представления подробного толкания по-разному: различные цвета текста и фона ("левый" и синий, и "правый" и красный, соответственно).

  4. Я добавил код в контроллер подробного представления, чтобы сохранить и восстановить состояние свойств текста и цвета фона: encodeRestorableStateWithCoder(_:) а также decodeRestorableStateWithCoder(_:), Также я реализовал viewDidLoad() чтобы отразить значения этих свойств в представлении. Всякий раз, когда он создается и передается в навигацию через переход, свойства сначала устанавливаются, а затем используются для настройки представления в viewDidLoad(), Всякий раз, когда он создается во время восстановления, свойства устанавливаются в decodeRestorableStateWithCoder(_:) и так же используется в viewDidLoad(),

... но когда я запускаю этот код, последняя выбранная вкладка восстанавливается, но только до контроллера вида сверху - слева или справа, а не детали. Интересно, что цвет фона, последний установленный для контроллера детального вида, мигает на мгновение.

Я поместил точки останова в encodeRestorableStateWithCoder(_:) а также decodeRestorableStateWithCoder(_:), но только первый из них выполняется (кодировать).

  1. Задумываясь о том, что может отсутствовать, я пошел дальше и реализовал приложение делегата application(_:viewControllerWithRestorationIdentifierPath:coder:)(возвращает всегда ноль, но протоколирование пройденных компонентов пути).

В документации не очень ясно, нужен ли этот метод или нет, и в любом случае все контроллеры представления, кроме детали, кажутся восстановленными идеально даже без него. Я добавил код для создания экземпляра каждого контроллера представления на основе последнего компонента пути (т. Е. Идентификатора восстановления этого контроллера) и его возврата.

Теперь decodeRestorableStateWithCoder(_:) вызывается, но навигация все еще возвращается к контроллеру вида сверху вкладки через доли секунды.

Так, что происходит? Чего мне не хватает для реализации сохранения и восстановления состояния в приложении панели вкладок + контроллера навигации?

1 ответ

Решение

ИСПРАВЛЕНО: Итак, с моим кодом было несколько проблем...

  1. Оказывается, в моем случае мне не нужно реализовывать application(_:viewControllerWithRestorationIdentifierPath:coder:), (см. комментарии к этому ответу)

  2. Мои реализации encodeRestorableStateWithCoder(_:) а также decodeRestorableStateWithCoder(_:)не звонили super (как предложено в принятом ответе на вопрос выше).

  3. наконец, у меня появился нужный контроллер представления (деталь), но состояние его подпредставлений (содержимое текстовой метки и цвет фона основного вида) было в исходном пустом состоянии (не восстанавливается до своего последнего состояния -ie, содержимое текстовой метки) и цвет бг). Как уже упоминалось в этом вопросе, viewDidLoad() не вызывается сразу после decodeRestorableStateWithCoder(_:) (как я и предполагал), поэтому вместо этого я вызываю общий метод из обоих viewDidLoad() а также decodeRestorableStateWithCoder(_:) обновить пользовательский интерфейс.

Как обычно, я поспешил опубликовать вопрос, прежде чем искать или пробовать достаточно модификаций в моем коде (мои извинения...).

Я надеюсь, что это по крайней мере помогает кому-то еще.

Как обычно, я подожду пару дней, прежде чем принять свой собственный ответ, на случай, если кто-то прольет дополнительный свет.

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