Глядя, чтобы понять жизненный цикл iOS UIViewController


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

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

12 234

12 ответов:

все эти команды вызываются автоматически в соответствующее время iOS при загрузке/представлении / скрытии контроллера вида. Важно отметить, что эти методы прикреплены к UIViewController, а не UIViews сами по себе. Вы не получите ни одной из этих функций, просто используя 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/

A view controller's lifecycle, diagrammed

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

loadView()

loadViewIfNeeded ()

viewDidLoad ()

viewWillAppear (_animated: Bool)

viewWillLayoutSubviews ()

viewDidLayoutSubviews()

viewDidAppear(_ анимированных: Бул)

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

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

3. viewDidLoad

The 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

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

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

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

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

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

8. viewWillDisappear

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

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

4. viewWillAppear (_animated: Bool)

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

5. viewWillLayoutSubviews ()

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

6. viewDidLayoutSubviews()

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

7. viewDidAppear (_animated: Bool)

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

8. viewWillDisappear(_ анимированных: Бул)

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

9. viewDidDisappear (_animated: Bool)

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

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

вызывается, когда вид Переход.

11. willMove (toParentViewController parent: UIViewController?)

12. didMove (toParentViewController parent: UIViewController?)

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

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

13. didReceiveMemoryWarning()

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

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

enter image description here

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

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

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

там много устаревшей и неполной информации. Ибо 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 или более раз.

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

на этом изображении показаны допустимые переходы состояний между различными методами обратного вызова view ‘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.

согласно яблоку docs

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

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

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

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

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