-[UIViewController viewWillAppear:]
和之间有什么区别-[UIViewController viewDidAppear:]
?
-[UIViewController viewWillAppear:]
和之间有什么区别-[UIViewController viewDidAppear:]
?
Answers:
总的来说,这就是我要做的:
1)ViewDidLoad-每当我向视图添加控件时,应立即将其与该视图一起显示,然后将其放在ViewDidLoad方法中。基本上,只要将视图加载到内存中,就会调用此方法。因此,例如,如果我的视图是带有3个标签的表单,则可以在此处添加标签;没有这些形式,视图将永远不存在。
2)ViewWillAppear:我通常使用ViewWillAppear只是为了更新表单上的数据。因此,对于上面的示例,我将使用它来将域中的数据实际加载到表单中。创建UIView相当昂贵,您应该避免在ViewWillAppear方法上执行尽可能多的操作,因为调用该方法时,它意味着iPhone已经准备好向用户显示UIView,而您在此处所做的任何繁重的工作将以非常明显的方式影响性能(例如动画被延迟等)。
3)ViewDidAppear:最后,我使用ViewDidAppear为需要很长时间才能执行的事情启动新线程,例如进行webservice调用以获取上述表单的额外数据,这是因为视图已经存在并正在显示给用户,则可以在获取数据时向用户显示一个漂亮的“等待”消息。
viewWillAppear
什么意思?您是说要通过网络下载?但是,您还建议下载内容viewDidAppear
吗?
ViewDidAppear
进行操作,很容易使用户对UI
viewDidLoad === >>>将您的初始化代码放在这里。不要放置在视图生命周期中可能会更改的动态数据。因此,如果您要从核心数据中提取数据,则在此视图的生命周期内这种情况可能会发生变化时,您不想在此处进行操作。例如:说您有一个选项卡控制器。您从tab1切换到tab2,并在tab2中的模型上进行了更改。如果返回tab1并且您的模型代码在viewDidLoad中完成,则不会更新(假设您未使用KVO或NSFetchedResultsController等)。
viewWillAppear === >>>每当视图即将出现时,无论视图是否已在内存中,都会调用此方法。将您的动态代码放在这里,例如模型逻辑。
viewDidAppear === >>>仅在确定视图在屏幕上(例如网络调用)时,才需要执行昂贵的操作。
注意:如果您的应用程序是后台运行并返回到前台,则需要使用NSNotificationCenter进行处理。我在下面的注释中为此编写了代码。您可能认为viewWillAppear / viewDidAppear将触发。在此处放置一个断点并对其进行测试。它不会开火。因此,如果您的应用在后台运行时发生了变化,则需要使用通知进行更新。
viewWillAppear
在加载实际视图之前将调用该方法。
viewDidAppear
当视图已经加载并且想要显示某些内容时,将调用该方法。
一些观察:
viewDidLoad
首次实例化视图时调用该方法。IBOutlet
引用是在调用它之前被连接的,而不是在此之前。但是frame
,视图的调用可能尚未建立。这是添加/配置子视图及其关联约束的好地方。但是,如果您要frame
根据主视图的尺寸进行任何手动的值配置,则这些框架的配置应推迟到viewWillAppear
或viewDidLayoutSubviews
。
viewWillAppear
当视图层次结构中的视图呈现即将开始时,将调用该方法。值得注意的是,这是在视图呈现的动画(如果有)的开始处调用的。viewWillDisappear
当离开此视图的过渡开始时,显然会调用它的同伴。
viewDidAppear
当完成视图的呈现时,尤其是在完成所有关联的动画之后,将调用此方法。viewDidDisappear
当完成离开此视图的转换时,显然会调用它的同伴。
两个重要的警告:
viewDidLoad
首次实例化视图时,仅调用一次,并且仅调用一次。另一方面,不仅会在首次显示视图时调用,viewWillAppear
而且viewDidAppear
还会在以后的每一次重新显示所讨论的相同视图时调用。例如,当您首次显示视图时,将同时调用这三种方法。如果有问题的观点随后呈现随后被解雇时,另一种观点认为viewWillAppear
,并viewDidAppear
在有问题的视图添加和动画回视图层次一般会被再次调用,但viewDidLoad
不会。viewDidLoad
仅在首次创建此特定实例时调用。
因此,如果您希望每次重新显示视图时都执行某项操作(例如,关闭或弹出视图),请在viewWillAppear
或中进行操作viewDidAppear
。如果希望仅在首次实例化视图时才发生,请在中进行viewDidLoad
。
的调用viewWillAppear
并不保证将完全完成向该视图的转换。值得注意的是,如果您使用的是由实时用户输入驱动的交互式转换,但是可以取消该交互式转换。即,仅因为viewWillAppear
被调用,并不意味着viewDidAppear
将被调用。通常是这样,但是如果取消了交互式手势,则不会(因为过渡从未完成)。
在WWDC 2013上,在交互式过渡的上下文中,演示者开玩笑说应将其重命名viewWillAppear
为“ viewMightAppear
或viewWillProbablyAppear
或iReallyWishThisViewWouldAppear
”。
内置交互式手势的一个示例是当UINavigationController
您使用时,您“从左边缘滑动”以启动视图弹出。该viewWillAppear
会呼吁给你如雨后春笋般冒出的观点,但如果取消,“从左侧边缘滑动”,以返回到从中启动此弹出的姿态来看,在弹出被取消,viewDidAppear
该视图你开始弹出到永远不会被调用。
这样做的最终结果是,您应注意不要编写假定每个viewWillAppear
最终都会调用的代码viewDidAppear
。如果取消过渡,则情况并非如此。
1)ViewWillAppear:该视图实际上已加载到内存中,在视图控制器中被调用一次并具有其框架,但仍未向用户显示
2)ViewDidAppear:控制器已添加到视图层次结构中,因此您可以将其呈现给下一个控制器,并且该视图确实布局了子视图
总结一下:
-viewWillAppear->更新数据(从表视图重新加载数据)
-viewDidAppear->昂贵的操作(具有良好进度的API调用!)
用例,即我什么时候应该使用哪个?
viewDidLoad
-当标签,按钮(即任何控件/子视图)连接到视图的界面文件时,并且如果您想同时加载所有这些视图和ViewController的视图,以及是否要将其一次加载到内存中并完成了
viewWillAppear
-例如,您希望每次viewController出现在屏幕上时更改视图的背景颜色。或者更现实的是,如果您想在白天的晚上使用DarkMode背景色,并在白天使用背景视图的浅色,请在viewWillAppear
另一个很好的用例在这里 https://stackoverflow.com/a/39395865/5438240
还要注意,如果您使用的是Navigation stack(UINavigationController
),则将要弹出的viewController被viewWillDisappear()
调用,而接下来将位于堆栈顶部的ViewController将被viewWillAppear()
调用