Глядя на понимание жизненного цикла iOS UIViewController

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

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

Ответ 1

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

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

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

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

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

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

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

Ответ 3

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

  • loadView()

  • loadViewIfNeeded()

  • viewDidLoad()

  • viewWillAppear(_ animated: Bool)

  • viewWillLayoutSubviews()

  • viewDidLayoutSubviews()

  • viewDidAppear(_ animated: Bool)

  • viewWillDisappear(_ animated: Bool)

  • viewDidDisappear(_ animated: Bool)

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

1. loadView

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

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

2. loadViewIfNeeded

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

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

3. viewDidLoad

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

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

4. viewWillAppear

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

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

5. viewWillLayoutSubviews

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

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

6. viewDidLayoutSubviews

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

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

7. viewDidAppear

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

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

8. viewWillDisappear

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

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

9. viewDidDisappear

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

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

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

Если вы подкласс UIViewController, вы должны вызвать супер реализацию этого метода, даже если вы не используете NIB. (Для удобства метод init по умолчанию сделает это за вас, и для обоих аргументов этого метода будет указано значение nil.) В указанном NIB прокси-серверу Владельца файла должен быть установлен класс для вашего подкласса контроллера представления с выходом представления подключен к основному виду. Если вы вызываете этот метод с именем nil -loadView метод этого класса -loadView попытается загрузить NIB, имя которого совпадает с вашим классом контроллера представления. Если такого NIB на самом деле не существует, вы должны либо вызвать -setView: перед -view, либо переопределить метод -loadView для программной настройки ваших представлений.

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

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

Ответ 4

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()

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

7. viewDidAppear (_ animated: Bool)

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

8. viewWillDisappear (_ animated: Bool)

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

9. viewDidDisappear (_ animated: Bool)

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

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

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

11. willMove (родитель toParentViewController: UIViewController?)

12. didMove (родитель toParentViewController: UIViewController?)

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

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

13. didReceiveMemoryWarning()

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

Ответ 5

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

enter image description here

Ответ 6

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

Ответ 7

Давайте сосредоточимся на методах, которые отвечают за жизненный цикл 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.

Ответ 8

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

Ответ 9

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

  • loadView [а]
  • viewDidLoad [а]
  • viewWillAppear
  • viewWillLayoutSubviews - первая временная граница завершена
  • viewDidLayoutSubviews
  • viewDidAppear
  • * viewWillLayoutSubviews [b]
  • * viewDidLayoutSubviews [b]

<суб > <Сильного > Сноска: Суб >

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

<суб > (b) Может называться дополнительным 0 или более раз. Суб >

Ответ 10

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

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

Действительные государственные переходы:


Взято из: https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Art/UIViewController класса Reference_2x.png

Ответ 11

init(coder:)

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

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

viewDidLoad()

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

viewWillAppear(_:)

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

viewWillDisappear(_:)

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

Ответ 12

Согласно Apple doc - Начните разрабатывать приложения для iOS (Swift) - Работайте с контроллерами представления - Поймите жизненный цикл контроллера представления

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

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

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

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

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