Хотите понять жизненный цикл iOS UIViewController

Не могли бы вы объяснить мне, как правильно управлять UIViewController жизненный цикл?

В частности, я хотел бы знать, как использовать Initialize, ViewDidLoad, ViewWillAppear, ViewDidAppear, ViewWillDisappear, ViewDidDisappear, ViewDidUnload а также Dispose методы в Mono Touch для UIViewController учебный класс.

12 ответов

Решение

Все эти команды вызываются автоматически в соответствующее время iOS, когда вы загружаете / представляете / скрываете контроллер представления. Важно отметить, что эти методы прикреплены к UIViewController и не UIView Сами. Вы не получите ни одну из этих функций, просто используя UIView,

На сайте Apple есть отличная документация. Вставляя просто, хотя:

  • ViewDidLoad - Вызывается при создании класса и загрузке из XIB. Отлично подходит для начальной настройки и разовой работы.

  • ViewWillAppear - Вызывается непосредственно перед отображением вашего представления, хорошо для скрытия / отображения полей или любых операций, которые вы хотите выполнять каждый раз, когда представление становится видимым. Поскольку вы можете переходить назад и вперед между представлениями, это будет вызываться каждый раз, когда ваше представление собирается появиться на экране.

  • ViewDidAppear - Вызывается после появления представления - отличное место для запуска анимации или загрузки внешних данных из API.

  • ViewWillDisappear / DidDisappear - та же идея, что и ViewWillAppear / ViewDidAppear,

  • ViewDidUnload / ViewDidDispose - В Objective C, это то место, где вы проводите очистку и освобождение материала, но это обрабатывается автоматически, так что вам не нужно ничего делать здесь.

Жизненный цикл UIViewController представлен здесь:

http://rdkw.wordpress.com/2013/02/24/ios-uiviewcontroller-lifecycle/

Жизненный цикл контроллера представления в виде диаграммы

Это для последних версий iOS (изменено с помощью Xcode 9.3, Swift 4.1). Ниже приведены все этапы, которые делают жизненный цикл UIViewController полный.

loadView ()

loadViewIfNeeded ()

viewDidLoad ()

viewWillAppear (_ animated: Bool)

viewWillLayoutSubviews ()

viewDidLayoutSubviews ()

viewDidAppear (_ animated: Bool)

viewWillDisappear (_ animated: Bool)

viewDidDisappear (_ animated: Bool)

Позвольте мне объяснить все эти этапы.

1. loadView

Это событие создает представление, которым управляет контроллер. Он вызывается только тогда, когда контроллер представления создается программно. Это делает его хорошим местом для создания ваших представлений в коде.

This is where subclasses should create their custom view hierarchy if they aren't using a nib. 
Should never be called directly. 

2. loadViewIfNeeded

Если инкрустировать вид тока viewController еще не был установлен, тогда этот метод загрузит представление, но помните, это доступно только в iOS >=9.0. Так что, если вы поддерживаете iOS <9.0, то не ожидайте, что она войдет в картину.

Loads the view controller's view if it has not already been set.

3. viewDidLoad

viewDidLoad Событие вызывается только тогда, когда представление создано и загружено в память, но границы для вида еще не определены. Это хорошее место для инициализации объектов, которые будет использовать контроллер представления.

Called after the view has been loaded. For view controllers created in code, this is after -loadView.
For view controllers unarchived from a nib, this is after the view is set.

4. viewWillAppear

Это событие уведомляет viewController всякий раз, когда вид появляется на экране. На этом шаге у представления есть границы, которые определены, но ориентация не установлена.

Called when the view is about to made visible. Default does nothing.

5. viewWillLayoutSubviews

Это первый шаг в жизненном цикле, когда границы завершаются. Если вы не используете ограничения или Auto Layout, вы, вероятно, захотите обновить подпредставления здесь. Это доступно только в iOS >=5.0. Так что, если вы поддерживаете iOS <5.0, то не ожидайте, что она войдет в картину.

Called just before the view controller's view's layoutSubviews method is invoked.
Subclasses can implement as necessary. The default is a nop.

6. viewDidLayoutSubviews

Это событие уведомляет контроллер представления о том, что подпредставления были настроены. Это хорошее место для внесения любых изменений в подпредставления после их установки. Это доступно только в iOS >=5.0. Так что, если вы поддерживаете iOS <5.0, то не ожидайте, что она войдет в картину.

Called just after the view controller's view's layoutSubviews method is invoked.
Subclasses can implement as necessary. The default is a nop.

7. viewDidAppear

viewDidAppear событие срабатывает после того, как представление представлено на экране. Что делает его хорошим местом для получения данных из бэкэнд-сервиса или базы данных.

Called when the view has been fully transitioned onto the screen.
Default does nothing

8. viewWillDisappear

viewWillDisappear событие срабатывает, когда вид представлен viewController собирается исчезнуть, уволить, прикрыть или спрятаться за другим viewController, Это хорошее место, где вы можете ограничить свои сетевые вызовы, сделать недействительным таймер или освободить объекты, связанные с этим. viewController,

Called when the view is dismissed, covered or otherwise hidden.

9. viewDidDisappear

Это последний шаг жизненного цикла, к которому может обратиться любой, так как это событие запускается сразу после просмотра представленного viewController исчез, уволен, скрыт или скрыт.

Called after the view was dismissed, covered or otherwise hidden. 
Default does nothing

Теперь, согласно Apple, когда вы реализуете эти методы, вы должны не забыть вызвать super реализация этого конкретного метода.

If you subclass UIViewController, you must call the super implementation of this
method, even if you aren't using a NIB.  (As a convenience, the default init method will do this for you,
and specify nil for both of this methods arguments.) In the specified NIB, the File's Owner proxy should
have its class set to your view controller subclass, with the view outlet connected to the main view. If you
invoke this method with a nil nib name, then this class' -loadView method will attempt to load a NIB whose
name is the same as your view controller's class. If no such NIB in fact exists then you must either call
-setView: before -view is invoked, or override the -loadView method to set up your views programatically.

Надеюсь, это помогло. Благодарю.

ОБНОВЛЕНИЕ - Как @ThomasW указал внутри комментария viewWillLayoutSubviews а также viewDidLayoutSubviews также будет вызываться в другое время, когда загружаются подпредставления основного представления, например, когда загружаются ячейки табличного представления или представления коллекции.

iOS 10,11 (Swift 3.1, Swift 4.0)

В соответствии с UIViewController в UIKit Разработчики,

1. loadView ()

Именно здесь подклассы должны создавать свою собственную иерархию представлений, если они не используют перо. Никогда не должен вызываться напрямую.

2. loadViewIfNeeded ()

Загружает представление контроллера представления, если оно еще не было установлено.

3. viewDidLoad ()

Вызывается после того, как представление было загружено. Для контроллеров представления, созданных в коде, это после -loadView. Для контроллеров представления, разархивированных с пера, это после того, как представление установлено.

4. viewWillAppear (_ animated: Bool)

Вызывается, когда представление собирается сделать видимым. По умолчанию ничего не делает

5. viewWillLayoutSubviews()

Вызывается сразу после вызова метода layoutSubviews представления контроллера представления. Подклассы могут реализовывать по мере необходимости.

6. viewDidLayoutSubviews ()

Вызывается, когда размер, положение и ограничения применяются ко всем объектам.

7. viewDidAppear (_ animated: Bool)

Вызывается, когда вид полностью перешел на экран. По умолчанию ничего не делает

8. viewWillDisappear(анимированный: Bool)

Вызывается, когда представление закрыто, скрыто или иным образом скрыто. По умолчанию ничего не делает

9. viewDidDisappear (_ animated: Bool)

Вызывается после того, как представление было закрыто, скрыто или иным образом скрыто. По умолчанию ничего не делает

10. viewWillTransition(для размера: CGSize, с координатором: UIViewControllerTransitionCoordinator)

Вызывается, когда представление переходное.

11. willMove (родительский элемент toParentViewController: UIViewController?)

12. didMove (родительский элемент toParentViewController: UIViewController?)

Эти два метода общедоступны для вызова подклассов контейнера при переходе между дочерними контроллерами. Если они переопределены, переопределения должны обеспечить вызов супер.

Аргумент parent в обоих этих методах равен nil, когда дочерний элемент удаляется из родительского элемента; в противном случае он равен новому родительскому контроллеру представления.

13. didReceiveMemoryWarning ()

Вызывается, когда родительское приложение получает предупреждение о памяти. На iOS 6.0 он больше не будет очищать вид по умолчанию.

Начиная с iOS 6 и выше. Новая диаграмма выглядит следующим образом:

Давайте сосредоточимся на методах, которые отвечают за жизненный цикл UIViewController:

  • Создание:

    - (void)init

    - (void)initWithNibName:

  • Просмотр создания:

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

    - (UIView *)initWithCoder:(NSCoder *)coder

  • Обработка изменения состояния просмотра:

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)animated

    - (void)viewDidAppear:(BOOL)animated

    - (void)viewWillDisappear:(BOOL)animated

    - (void)viewDidDisappear:(BOOL)animated

    - (void)viewDidUnload

  • Обработка предупреждений памяти:

    - (void)didReceiveMemoryWarning

  • Deallocation

    - (void)viewDidUnload

    - (void)dealloc

Диаграмма жизненного цикла UIViewController

Для получения дополнительной информации, пожалуйста, взгляните на UIViewController Class Reference.

Методы viewWillLayoutSubviews а также viewDidLayoutSubviews не упоминаются в диаграммах, но они называются между viewWillAppear а также viewDidAppear, Их можно вызывать несколько раз.

Ответ Хайдера является правильным для предварительной версии iOS 6. Однако, начиная с iOS 6, viewDidUnload и viewWillUnload никогда не вызываются. Документы заявляют: "Представления больше не удаляются в условиях нехватки памяти, поэтому этот метод никогда не вызывается".

Здесь много устаревшей и неполной информации. Только для iOS 6 и новее:

  1. loadView [а]
  2. viewDidLoad [а]
  3. viewWillAppear
  4. viewWillLayoutSubviews это первый раз, когда границы завершены
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. *viewWillLayoutSubviews [Ь]
  8. *viewDidLayoutSubviews [Ь]

Примечания:

(а) - Если вы вручную обнуляете свое мнение во время didReceiveMemoryWarning , loadView а также viewDidLoad будет вызван снова. То есть по умолчанию loadView а также viewDidLoad вызывается только один раз для каждого экземпляра контроллера представления.

(б) Может вызываться дополнительно 0 или более раз.

Объяснение изменений состояния в официальном документе: https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/index.html

На этом изображении показаны действительные переходы между различными методами обратного вызова "will" и "did".

Действительные Государственные Переходы

init(coder:)

Когда вы создаете представления своего приложения в раскадровке, init(coder:) это метод, который вызывается для создания экземпляра вашего контроллера представления и воплощения его в жизнь. Контракт для этого метода фактически определен в протоколе NSCoding, поэтому вы не увидите его в UIViewController документация.

Когда вызывается этот метод, ваш вид, скорее всего, будет отображаться в ближайшем будущем (или в ближайшем будущем), но на данный момент нет никакой гарантии, что он действительно будет отображаться. Так что сейчас самое время начать приводить порядок в порядок, но не слишком много здесь, иначе вы будете тратить впустую вычислительные мощности. В этом методе вы можете создавать экземпляры зависимостей, включая подпредставления, которые вы добавляете в ваше представление программно. И обратите внимание, что init(coder:) вызывается только один раз в течение жизни объекта, как и все методы init.

viewDidLoad()

Вызывается после init(coder:) когда представление загружается в память, этот метод также вызывается только один раз в течение срока службы объекта контроллера представления. Это отличное место для инициализации или настройки любого вида, которые вы не делали в раскадровке. Возможно, вы захотите добавить подпредставления или автоматические ограничения макета программно - если это так, то это отличное место, чтобы сделать любой из них. Обратите внимание, что только то, что представление было загружено в память, не обязательно означает, что оно будет отображаться в ближайшее время - для этого вы захотите посмотреть viewWillAppear, Ох, и не забудьте позвонить super.viewDidLoad() в вашей реализации, чтобы убедиться, что viewDidLoad вашего суперкласса получает шанс выполнить свою работу - я обычно вызываю super прямо в начале реализации.

viewWillAppear(_:)

Всегда звонил после viewDidLoad (по понятным причинам, если вы об этом думаете), и как раз перед тем, как представление появится на экране для пользователя, viewWillAppear называется. Это дает вам возможность выполнить любую последнюю настройку просмотра, запустить сетевой запрос (в другом классе, конечно) или обновить экран. В отличие от viewDidLoad, viewWillAppear вызывается при первом отображении представления, а также при повторном отображении представления, поэтому его можно вызывать несколько раз в течение срока службы объекта контроллера представления. Он вызывается, когда представление должно появиться в результате нажатия пользователем кнопки "Назад", закрытия модального диалога, когда в контроллере панели вкладок выбрана вкладка контроллера представления, или по ряду других причин. Обязательно позвони super.viewWillAppear() в какой-то момент реализации - я обычно делаю это первым делом.

viewWillDisappear(_:)

Похожий на viewWillAppearэтот метод вызывается непосредственно перед тем, как вид исчезнет с экрана. И как viewWillAppearэтот метод может вызываться несколько раз в течение срока службы объекта контроллера представления. Он вызывается, когда пользователь уходит от экрана - возможно, закрывая экран, выбирая другую вкладку, нажимая кнопку, которая показывает модальное представление, или перемещаясь дальше вниз по иерархии навигации. Это отличное место, чтобы скрыть клавиатуру, сохранить состояние и, возможно, отменить запущенные таймеры или сетевые запросы. Как и другие методы в жизненном цикле контроллера представления, обязательно вызовите super в какой-то момент viewWillDisappear,

Согласно Apple, документы

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

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

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

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

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

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