Хотите понять жизненный цикл iOS UIViewController - PullRequest
271 голосов
/ 06 апреля 2011

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

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

Ответы [ 11 ]

399 голосов
/ 26 сентября 2012

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

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

A view controller's lifecycle, diagrammed

388 голосов
/ 06 апреля 2011

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

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

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

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

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

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

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

148 голосов
/ 21 сентября 2015

Это для последних версий 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

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

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

2.loadViewIfNeeded

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

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

3.viewDidLoad

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

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

4.viewWillAppear

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

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

5.viewWillLayoutSubviews

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

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

6.viewDidLayoutSubviews

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

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

7.viewDidAppear

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

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

8.viewWillDisappear

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

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

9.viewDidDisappear

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

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

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

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

Надеюсь, это помогло.Спасибо.

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

40 голосов
/ 21 августа 2017

iOS 10,11 (Swift 3.1, Swift 4.0)

По словам UIViewController у UIKit разработчиков,

1. loadView ()

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

2. loadViewIfNeeded ()

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

3. viewDidLoad ()

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

4. viewWillAppear (_ animated: Bool)

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

5. viewWillLayoutSubviews ()

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

6. viewDidLayoutSubviews ()

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

7. viewDidAppear (_ animated: Bool)

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

8. viewWillDisappear (_ animated: Bool)

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

9. viewDidDisappear (_ animated: Bool )

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

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

Вызывается при переходе вида.

11. willMove (toParentViewController parent: UIViewController?)

12. didMove (toParentViewController parent: UIViewController?)

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

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

13. didReceiveMemoryWarning ()

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

28 голосов
/ 08 июля 2015

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

enter image description here

19 голосов
/ 18 ноября 2014

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

18 голосов
/ 12 мая 2016

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

  • Распределение

    - (void)viewDidUnload

    - (void)dealloc

UIViewController's lifecycle diagram

Дляболее подробную информацию смотрите на UIViewController Class Reference .

16 голосов
/ 06 сентября 2015

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

  1. loadView [a]
  2. viewDidLoad [a]
  3. viewWillAppear
  4. viewWillLayoutSubviews - первый раз, когда границы окончательно определены
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews [b]
  8. * viewDidLayoutSubviews [b]

Сноски:

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

(b) Можно назвать еще 0 или более раз.

16 голосов
/ 23 апреля 2014

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

10 голосов
/ 21 октября 2014

Объяснение государственных переходов в официальном документе: 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

...