Answers:
当您加载/显示/隐藏视图控制器时,iOS将在适当的时候自动调用所有这些命令。重要的是要注意,这些方法是附属于自身的,UIViewController
而不是附属于UIView
自身的。仅使用,您将不会获得任何这些功能UIView
。
有一个关于苹果公司的网站上丰富的文档在这里。简单地输入:
ViewDidLoad
-在创建类并从xib加载时调用。非常适合初始设置和一次性工作。
ViewWillAppear
-在视图出现之前立即调用,非常适合隐藏/显示字段或您希望在视图可见之前每次进行的任何操作。因为您可能在视图之间来回切换,所以每次视图将出现在屏幕上时都会调用此方法。
ViewDidAppear
-在视图出现后调用-是启动动画或从API加载外部数据的好地方。
ViewWillDisappear
/ DidDisappear
-相同的思路ViewWillAppear
/ ViewDidAppear
。
ViewDidUnload
/ ViewDidDispose
-在Objective-C中,您可以在此处进行清理和发布,但这是自动处理的,因此您在这里实际上不需要做很多事情。
更新:ViewDidUnload在iOS 6中已弃用,因此相应地更新了答案。
UIViewController生命周期的示意图如下:
使用Xamarin Native / Mono Touch的优势在于它使用了本机API,因此它遵循与Apple文档中相同的ViewController生命周期。
这是针对最新的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
此事件创建/加载控制器管理的视图。它可以从关联的nib文件加载,UIView
如果找到null,则为空。这使它成为以编程方式在代码中创建视图的好地方。
如果子类不使用笔尖,则应在此处创建其自定义视图层次结构。永远不要直接调用。仅当以编程方式创建视图并将根视图分配给
view
属性时,才重写此方法。重写loadView时不要调用super方法。
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
viewWillDisappear
当所呈现的视图viewController
即将消失,解散,掩盖或隐藏在其他对象后面时,将触发该事件viewController
。在这里,您可以限制网络调用,使计时器无效或释放与其绑定的对象viewController
。
当视图被关闭,覆盖或其他隐藏时调用。
9。 viewDidDisappear
这是生命周期的最后一步,任何人都可以解决,因为呈现的视图viewController
消失,消失,覆盖或隐藏之后,此事件才会触发。
在视图被撤消,覆盖或其他隐藏之后调用。默认不执行任何操作
现在,按照Apple的方法,在实现此方法时,您应该记住要调用super
该特定方法的实现。
如果您将UIViewController子类化,则即使您未使用NIB,也必须调用此方法的超级实现。(为方便起见,默认的init方法将为您执行此操作,并为这两个方法参数都指定nil。)在指定的NIB中,File的Owner代理应将其类设置为您的视图控制器子类,并带有view出口连接到主视图。如果您使用nil nib名称调用此方法,则此类的
-loadView
方法将尝试加载名称与视图控制器的类相同的NIB。如果实际上不存在这样的NIB,则您必须在调用-setView:
之前-view
调用,或者重写该-loadView
方法以编程方式设置视图。
希望这会有所帮助。谢谢。
更新 -正如@ThomasW在注释中指出的那样,viewWillLayoutSubviews
并且viewDidLayoutSubviews
在加载主视图的子视图时(例如,在加载表视图或集合视图的单元格时)也会在其他时间调用。
更新 -正如@Maria在评论中指出的,说明loadView
已更新
viewWillLayoutSubviews
并且viewDidLayoutSubviews
还会在加载主视图的子视图的其他时间调用,例如,在加载表视图或集合视图的单元格时。
viewWillAppear
viewDidAppear
viewDidDisappear
。您必须在某个时候叫超级。
iOS 10,11 (Swift 3.1,Swift 4.0)
据UIViewController
在UIKit
开发商,
1. loadView()
如果子类不使用nib,则应在此处创建其自定义视图层次结构。永远不要直接调用。
2. loadViewIfNeeded()
加载视图控制器的视图(如果尚未设置)。
3. viewDidLoad()
加载视图后调用。对于用代码创建的视图控制器,该命令位于-loadView之后。对于从笔尖未存档的视图控制器,这是在设置视图之后。
4. viewWillAppear(_动画:布尔)
在视图将变为可见时调用。默认不执行任何操作
5. viewWillLayoutSubviews()
在调用视图控制器的视图的layoutSubviews方法之前调用。子类可以根据需要实现。默认不执行任何操作。
6. viewDidLayoutSubviews()
在调用视图控制器的视图的layoutSubviews方法之后立即调用。子类可以根据需要实现。默认不执行任何操作。
7. viewDidAppear(_动画:布尔)
当视图完全过渡到屏幕上时调用。默认不执行任何操作
8. viewWillDisappear(_动画:布尔)
当视图被关闭,覆盖或其他隐藏时调用。默认不执行任何操作
9. viewDidDisappear(_动画:Bool)
在视图被撤消,覆盖或其他隐藏之后调用。默认不执行任何操作
10. viewWillTransition(大小:CGSize,协调器:UIViewControllerTransitionCoordinator)
当视图正在过渡时调用。
11. willMove(toParentViewController parent:UIViewController?)
12. didMove(toParentViewController parent:UIViewController?)
在子控制器之间转换时,这两种方法是公共的,供容器子类调用。如果它们被覆盖,则覆盖应确保调用超级。
当从其父级中移除子级时,这两种方法的父级参数均为nil。否则,它等于新的父视图控制器。
13. didReceiveMemoryWarning()
当父应用程序收到内存警告时调用。在iOS 6.0上,默认情况下将不再清除视图。
nib
在下面提到的是什么loadView
?
viewWillLayoutSubviews()
在ViewController的视图对象调用其layoutSubviews()
方法之前被调用
从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
解除分配
- (void)viewDidUnload
- (void)dealloc
有关更多信息,请参见UIViewController类参考。
Haider的答案对于iOS 6之前的版本是正确的。但是,从iOS 6开始,从未调用过viewDidUnload和viewWillUnload。该文档的状态:“视图不再低内存情况下,因此这种方法不会被调用清除。”
这里有很多过时和不完整的信息。仅适用于iOS 6及更高版本:
loadView
[一个]viewDidLoad
[一个]viewWillAppear
viewWillLayoutSubviews
是第一次确定界限viewDidLayoutSubviews
viewDidAppear
*
viewWillLayoutSubviews
[b]*
viewDidLayoutSubviews
[b]脚注:
(一) -如果你手动零出在你的看法didReceiveMemoryWarning
,loadView
并viewDidLoad
会被再次调用。也就是说,默认情况下loadView
,viewDidLoad
每个视图控制器实例仅被调用一次。
(b)可能被称为0次或多次。
viewWillLayoutSubviews
并且viewDidLayoutSubviews
还会在加载主视图的子视图的其他时间调用,例如,在加载表视图或集合视图的单元格时。
在官方文档中解释状态转换: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
按照Apple的文档-开始开发iOS应用(快速)-使用View Controllers-了解View Controller生命周期
viewDidLoad()
—在创建视图控制器的内容视图(其视图层次结构的顶部)并从情节提要中加载时调用。…使用此方法执行视图控制器所需的任何其他设置。
viewWillAppear()
—在将视图控制器的内容视图添加到应用程序的视图层次结构之前调用。使用此方法触发在屏幕上显示内容视图之前需要进行的任何操作
viewDidAppear()
—在将视图控制器的内容视图添加到应用程序的视图层次结构之后立即调用。使用此方法可以触发在屏幕上显示视图后立即进行的所有操作,例如获取数据或显示动画。
viewWillDisappear()
—在将视图控制器的内容视图从应用程序的视图层次结构中删除之前调用。使用此方法可以执行清除任务,例如提交更改或退出第一响应者状态。
viewDidDisappear()
—在从应用程序的视图层次结构中删除视图控制器的内容视图之后立即调用。使用此方法执行其他拆卸活动。