想要了解 iOS UIViewController 生命周期

发布于 2024-10-30 19:52:05 字数 342 浏览 5 评论 0原文

您能解释一下管理 UIViewController 生命周期的正确方法吗?

我特别想知道如何使用 InitializeViewDidLoadViewWillAppearViewDidAppearMono Touch 中 UIViewController 类的 ViewWillDisappearViewDidDisappearViewDidUnloadDispose 方法。

Could you explain me the correct manner to manage the UIViewController lifecycle?

In particular, I would like to know how to use Initialize, ViewDidLoad, ViewWillAppear, ViewDidAppear, ViewWillDisappear, ViewDidDisappear, ViewDidUnload and Dispose methods in Mono Touch for a UIViewController class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

坦然微笑 2024-11-06 19:52:05

当您加载/显示/隐藏视图控制器时,所有这些命令都会由 iOS 在适当的时间自动调用。需要注意的是,这些方法附加到 UIViewController 而不是 UIView 本身。仅使用 UIView 您无法获得任何这些功能。

Apple 网站此处提供了很棒的文档。简单地说:

  • ViewDidLoad - 在创建类并从 xib 加载时调用。非常适合初始设置和一次性工作。

  • ViewWillAppear - 在视图出现之前调用,适用于隐藏/显示字段或您希望每次在视图可见之前发生的任何操作。因为您可能会在视图之间来回切换,所以每次视图即将出现在屏幕上时都会调用此函数。

  • ViewDidAppear - 在视图出现后调用 - 启动动画或从 API 加载外部数据的好地方。

  • ViewWillDisappear/DidDisappear - 与 ViewWillAppear/ViewDidAppear 相同。

  • ViewDidUnload/ViewDidDispose - 在 Objective-C 中,这是你清理和释放东西的地方,但这是自动处理的,所以你实际上不需要做太多需要在这里做。

All these commands are called automatically at the appropriate times by iOS when you load/present/hide the view controller. It's important to note that these methods are attached to UIViewController and not to UIViews themselves. You won't get any of these features just using a UIView.

There's great documentation on Apple's site here. Putting in simply though:

  • ViewDidLoad - Called when you create the class and load from xib. Great for initial setup and one-time-only work.

  • ViewWillAppear - Called right before your view appears, good for hiding/showing fields or any operations that you want to happen every time before the view is visible. Because you might be going back and forth between views, this will be called every time your view is about to appear on the screen.

  • ViewDidAppear - Called after the view appears - great place to start an animations or the loading of external data from an API.

  • ViewWillDisappear/DidDisappear - Same idea as ViewWillAppear/ViewDidAppear.

  • ViewDidUnload/ViewDidDispose - In Objective-C, this is where you do your clean-up and release of stuff, but this is handled automatically so not much you really need to do here.

ι不睡觉的鱼゛ 2024-11-06 19:52:05

更新:ViewDidUnload 在 iOS 6 中已被弃用,因此相应地更新了答案。

UIViewController 生命周期如下图所示:

A view controller's Lifecycle, shown

使用 Xamarin Native/Mono Touch 的优点是,它使用本机 API,因此它遵循与 Apple 文档中相同的 ViewController 生命周期。

UPDATE: ViewDidUnload was deprecated in iOS 6, so updated the answer accordingly.

The UIViewController lifecycle is diagrammed here:

A view controller's lifecycle, diagrammed

The advantage of using Xamarin Native/Mono Touch, is that it uses the native APIs, and so it follows the same ViewController lifecycle as you would find in Apple's Documentation.

反目相谮 2024-11-06 19:52:05

这适用于最新的 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

此事件创建/加载控制器管理的视图。如果找到 null,它可以从关联的 nib 文件或空 UIView 加载。
这使得它成为以编程方式在代码中创建视图的好地方。

如果子类不使用笔尖,则应在此处创建自定义视图层次结构。
永远不应该直接调用。
仅当您以编程方式创建视图并将根视图分配给 view 属性时才重写此方法
重写时不要调用 super 方法
loadView

2. loadViewIfNeeded

如果当前 viewController 的视图尚未设置,则此方法将加载视图,但请记住,这仅在 iOS 中可用 >= 9.0。因此,如果您支持 iOS <9.0,则不要指望它会出现。

加载视图控制器的视图(如果尚未设置)。

3. viewDidLoad

viewDidLoad 事件仅在创建视图并将其加载到内存中但尚未定义视图边界时调用。这是初始化视图控制器将要使用的对象的好地方。

加载视图后调用。对于在代码中创建的视图控制器,这是在 -loadView 之后。
对于从笔尖取消归档的视图控制器,这是在设置视图之后。

4. viewWillAppear

每当视图出现在屏幕上时,此事件都会通知 viewController。在此步骤中,视图已定义边界,但未设置方向。

当视图即将变得可见时调用。默认不执行任何操作。

5. viewWillLayoutSubviews

这是生命周期中最终确定边界的第一步。如果您不使用约束或自动布局,您可能想在此处更新子视图。此功能仅适用于 iOS >=5.0。因此,如果您支持 iOS <5.0,则不要指望它会出现。

在调用视图控制器的视图的layoutSubviews方法之前调用。
子类可以根据需要实现。默认值为 nop。

6. viewDidLayoutSubviews

此事件通知视图控制器子视图已设置。这是在子视图设置后对其进行任何更改的好地方。此功能仅适用于 iOS >=5.0。因此,如果您支持 iOS <5.0,则不要指望它会出现。

在调用视图控制器的视图的layoutSubviews方法后立即调用。
子类可以根据需要实现。默认值为 nop。

7. viewDidAppear

viewDidAppear 事件在视图呈现在屏幕上后触发。这使得它成为从后端服务或数据库获取数据的好地方。

当视图完全转换到屏幕上时调用。
默认不执行任何操作

8。 viewWillDisappear

当呈现的 viewController 视图即将消失、解除、覆盖或隐藏在其他 后面时,viewWillDisappear 事件会触发>视图控制器。这是一个好地方,您可以在其中限制网络调用、使计时器无效或释放绑定到该 viewController 的对象。

当视图被解除、覆盖或以其他方式隐藏时调用。

9. viewDidDisappear

这是生命周期的最后一步,任何人都可以处理,因为在呈现的 viewController 视图消失、解除、覆盖或隐。

在视图被解除、覆盖或以其他方式隐藏后调用。
默认不执行任何操作

现在,根据 Apple,当您实现此方法时,您应该记住调用该特定方法的 super 实现。

如果您子类化 UIViewController,则必须调用此方法的超级实现,即使您没有使用 NIB。 (为方便起见,默认的 init 方法将为您执行此操作,并为该方法的两个参数指定 nil。)在指定的 NIB 中,文件所有者代理应将其类设置为您的视图控制器子类,并使用视图出口连接到主视图。如果您使用 nil nib 名称调用此方法,则此类的 -loadView 方法将尝试加载名称与视图控制器的类相同的 NIB。如果实际上不存在这样的 NIB,那么您必须在调用 -view 之前调用 -setView:,或者重写 -loadView 方法来设置以编程方式提高您的观点。

希望这有帮助。
谢谢。

更新 - 正如 @ThomasW 在注释中指出的那样,viewWillLayoutSubviewsviewDidLayoutSubviews 也会在加载主视图的子视图时调用,例如当加载表视图或集合视图的单元格时。

更新 - 正如 @Maria 在评论中指出的那样,loadView 的描述已更新

This is for latest iOS Versions(Modified with Xcode 9.3, Swift 4.1). Below are all the stages which makes the lifecycle of a UIViewController complete.

  • loadView()

  • loadViewIfNeeded()

  • viewDidLoad()

  • viewWillAppear(_ animated: Bool)

  • viewWillLayoutSubviews()

  • viewDidLayoutSubviews()

  • viewDidAppear(_ animated: Bool)

  • viewWillDisappear(_ animated: Bool)

  • viewDidDisappear(_ animated: Bool)

Let me explain all those stages.

1. loadView

This event creates/loads the view that the controller manages. It can load from an associated nib file or an empty UIView if null was found.
This makes it a good place to create your views in code programmatically.

This is where subclasses should create their custom view hierarchy if they aren't using a nib.
Should never be called directly.
Only override this method when you programmatically create views and assign the root view to the view property
Don't call super method when you override
loadView

2. loadViewIfNeeded

If incase the view of current viewController has not been set yet then this method will load the view but remember, this is only available in iOS >=9.0. So if you are supporting iOS <9.0 then don't expect it to come into the picture.

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

3. viewDidLoad

The viewDidLoad event is only called when the view is created and loaded into memory but the bounds for the view are not defined yet. This is a good place to initialise the objects that the view controller is going to use.

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

This event notifies the viewController whenever the view appears on the screen. In this step the view has bounds that are defined but the orientation is not set.

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

5. viewWillLayoutSubviews

This is the first step in the lifecycle where the bounds are finalised. If you are not using constraints or Auto Layout you probably want to update the subviews here. This is only available in iOS >=5.0. So if you are supporting iOS <5.0 then don't expect it to come into the picture.

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

This event notifies the view controller that the subviews have been setup. It is a good place to make any changes to the subviews after they have been set. This is only available in iOS >=5.0. So if you are supporting iOS <5.0 then don't expect it to come into the picture.

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 event fires after the view is presented on the screen. Which makes it a good place to get data from a backend service or database.

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

8. viewWillDisappear

The viewWillDisappear event fires when the view of presented viewController is about to disappear, dismiss, cover or hide behind other viewController. This is a good place where you can restrict your network calls, invalidate timer or release objects which is bound to that viewController.

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

9. viewDidDisappear

This is the last step of the lifecycle that anyone can address as this event fires just after the view of presented viewController has been disappeared, dismissed, covered or hidden.

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

Now as per Apple when you are implementing this methods you should remember to call super implementation of that specific method.

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.

Hope this helped.
Thanks.

UPDATE - As @ThomasW pointed inside comment viewWillLayoutSubviews and viewDidLayoutSubviews will also be called at other times when subviews of the main view are loaded, for example when cells of a table view or collection view are loaded.

UPDATE - As @Maria pointed inside comment, description of loadView was updated

荒人说梦 2024-11-06 19:52:05

iOS 10,11 (Swift 3.1,Swift 4.0)

根据 UIKitUIViewController > 开发人员,

1。 loadView()

如果子类不使用 笔尖。永远不应该直接调用。

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(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)

当视图转换时调用。

11. willMove(toParentViewController 父级:UIViewController?)

12. didMove(toParentViewController Parent: UIViewController?)

这两个方法是公共的,供容器子类在子控制器之间转换时调用。如果它们被覆盖,覆盖应确保调用 super。

当从父级中删除子级时,这两个方法中的父级参数均为 nil;否则它等于新的父视图控制器。

13. didReceiveMemoryWarning()

当父应用程序收到内存警告时调用。在 iOS 6.0 上,默认情况下将不再清除视图。

iOS 10,11 (Swift 3.1,Swift 4.0)

According to UIViewController in UIKit developers,

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

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

3. 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(_ animated: Bool)

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

5. viewWillLayoutSubviews()

Called just before the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. Default does nothing.

6. viewDidLayoutSubviews()

Called just after the view controller's view's layoutSubviews method is invoked. Subclasses can implement as necessary. Default does nothing.

7. viewDidAppear(_ animated: Bool)

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

8. viewWillDisappear(_ animated: Bool)

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

9. viewDidDisappear(_ animated: Bool)

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

10. viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)

Called when the view is Transitioning.

11. willMove(toParentViewController parent: UIViewController?)

12. didMove(toParentViewController parent: UIViewController?)

These two methods are public for container subclasses to call when transitioning between child controllers. If they are overridden, the overrides should ensure to call the super.

The parent argument in both of these methods is nil when a child is being removed from its parent; otherwise it is equal to the new parent view controller.

13. didReceiveMemoryWarning()

Called when the parent application receives a memory warning. On iOS 6.0 it will no longer clear the view by default.

浮萍、无处依 2024-11-06 19:52:05

从 iOS 6 及更高版本开始。新图如下:

在此处输入图像描述

As of iOS 6 and onward. The new diagram is as follows:

enter image description here

め七分饶幸 2024-11-06 19:52:05

让我们关注负责 UIViewController 生命周期的方法:

  • <强>创作:

    - (void)init

    - (void)initWithNibName:

  • 视图创建:

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

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

  • 处理视图状态更改:

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)动画

    - (void)viewDidAppear:(BOOL)动画

    - (void)viewWillDisappear:(BOOL)动画

    - (void)viewDidDisappear:(BOOL)动画

    - (void)viewDidUnload

  • 内存警告处理:

    - (void)didReceiveMemoryWarning

  • 释放< /strong>

    - (void)viewDidUnload

    - (void)dealloc

UIViewController 的生命周期图

有关更多信息,请查看 UIViewController 类参考

Let's concentrate on methods, which are responsible for the UIViewController's lifecycle:

  • Creation:

    - (void)init

    - (void)initWithNibName:

  • View creation:

    - (BOOL)isViewLoaded

    - (void)loadView

    - (void)viewDidLoad

    - (UIView *)initWithFrame:(CGRect)frame

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

  • Handling of view state changing:

    - (void)viewDidLoad

    - (void)viewWillAppear:(BOOL)animated

    - (void)viewDidAppear:(BOOL)animated

    - (void)viewWillDisappear:(BOOL)animated

    - (void)viewDidDisappear:(BOOL)animated

    - (void)viewDidUnload

  • Memory warning handling:

    - (void)didReceiveMemoryWarning

  • Deallocation

    - (void)viewDidUnload

    - (void)dealloc

UIViewController's lifecycle diagram

For more information please take a look on UIViewController Class Reference.

水染的天色ゝ 2024-11-06 19:52:05

图中未提及 viewWillLayoutSubviewsviewDidLayoutSubviews 方法,但它们是在 viewWillAppearviewDidAppear 之间调用的。它们可以被多次调用。

The methods viewWillLayoutSubviews and viewDidLayoutSubviews aren't mentioned in the diagrams, but these are called between viewWillAppear and viewDidAppear. They can be called multiple times.

铜锣湾横着走 2024-11-06 19:52:05

Haider 的答案对于 iOS 6 之前的版本是正确的。但是,从 iOS 6 开始,viewDidUnload 和 viewWillUnload 永远不会被调用。 文档 状态:“在内存不足的情况下不再清除视图,因此永远不会调用此方法。”

Haider's answer is correct for pre-iOS 6. However, as of iOS 6 viewDidUnload and viewWillUnload are never called. The docs state: "Views are no longer purged under low-memory conditions and so this method is never called."

风吹短裙飘 2024-11-06 19:52:05

这里有很多过时且不完整的信息。仅适用于 iOS 6 及更高版本

  1. loadView[a]
  2. viewDidLoad[a]
  3. viewWillAppear
  4. viewWillLayoutSubviews 是第一次确定边界
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews[b]
  8. * viewDidLayoutSubviews[b]


脚注:

<子>
(a) - 如果您在 didReceiveMemoryWarning 期间手动清空视图,loadViewviewDidLoad 将再次调用。也就是说,默认情况下,每个视图控制器实例仅调用 loadViewviewDidLoad 一次。

<子>
(b) 可能会被额外叫0次或更多次。

There's a lot of outdated and incomplete information here. For iOS 6 and newer only:

  1. loadView[a]
  2. viewDidLoad[a]
  3. viewWillAppear
  4. viewWillLayoutSubviews is the first time bounds are finalized
  5. viewDidLayoutSubviews
  6. viewDidAppear
  7. * viewWillLayoutSubviews[b]
  8. * viewDidLayoutSubviews[b]


Footnotes:


(a) - If you manually nil out your view during didReceiveMemoryWarning, loadView and viewDidLoad will be called again. That is, by default loadView and viewDidLoad only gets called once per view controller instance.


(b) May be called an additional 0 or more times.

命硬 2024-11-06 19:52:05

Explaining State Transitions in the official doc: https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/index.html

This image shows the valid state transitions between various view ‘will’ and ‘did’ callback methods

Valid State Transitions:


Taken from: https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Art/UIViewController Class Reference_2x.png

只有影子陪我不离不弃 2024-11-06 19:52:05

根据 Apple 文档 — 开始开发 iOS 应用程序 (Swift)
— 使用视图控制器 — 了解视图控制器生命周期

viewDidLoad() - 当创建视图控制器的内容视图(其视图层次结构的顶部)并从故事板加载时调用。
……
使用此方法执行视图控制器所需的任何其他设置。

viewWillAppear() - 在视图控制器的内容视图添加到应用程序的视图层次结构之前调用。使用此方法可以触发在屏幕上呈现内容视图之前需要发生的任何操作

viewDidAppear() - 在视图控制器的内容视图添加到应用程序的视图层次结构后立即调用。使用此方法可以触发视图在屏幕上呈现后立即发生的任何操作,例如获取数据或显示动画。

viewWillDisappear() - 在视图控制器的内容视图从应用程序的视图层次结构中删除之前调用。使用此方法执行清理任务,例如提交更改或放弃第一响应者状态。

viewDidDisappear() - 在视图控制器的内容视图从应用程序的视图层次结构中删除后调用。使用此方法执行其他拆卸活动。

As per Apple's doc — Start Developing iOS Apps (Swift)
— Work with View Controllers — Understand the View Controller Lifecycle

viewDidLoad()—Called when the view controller’s content view (the top of its view hierarchy) is created and loaded from a storyboard.

Use this method to perform any additional setup required by your view controller.

viewWillAppear()—Called just before the view controller’s content view is added to the app’s view hierarchy. Use this method to trigger any operations that need to occur before the content view is presented onscreen

viewDidAppear()—Called just after the view controller’s content view has been added to the app’s view hierarchy. Use this method to trigger any operations that need to occur as soon as the view is presented onscreen, such as fetching data or showing an animation.

viewWillDisappear()—Called just before the view controller’s content view is removed from the app’s view hierarchy. Use this method to perform cleanup tasks like committing changes or resigning the first responder status.

viewDidDisappear()—Called just after the view controller’s content view has been removed from the app’s view hierarchy. Use this method to perform additional teardown activities.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文