-viewWillAppear:和-viewDidAppear:有什么区别?

时间:2011-04-12 05:07:34

标签: iphone ios

-[UIViewController viewWillAppear:]-[UIViewController viewDidAppear:]之间的区别是什么?

14 个答案:

答案 0 :(得分:286)

一般来说,这就是我的工作:

1) ViewDidLoad - 每当我将控件添加到应与视图一起显示的视图时,我就把它放在ViewDidLoad方法中。基本上,只要将视图加载到内存中,就会调用此方法。例如,如果我的视图是带有3个标签的表单,我会在这里添加标签;没有这些形式,视图永远不会存在。

2) ViewWillAppear :我通常只使用ViewWillAppear来更新表单上的数据。因此,对于上面的示例,我将使用它来实际将数据从我的域加载到表单中。创建UIViews是相当昂贵的,你应该尽可能避免在ViewWillAppear方法上这样做,因为当它被调用时,这意味着iPhone已经准备好向用户显示UIView,你在这里做的任何重量将以非常明显的方式影响性能(如动画延迟等)。

3) ViewDidAppear :最后,我使用ViewDidAppear启动新线程,这些线程需要很长时间才能执行,比如执行webservice调用以获取表单的额外数据好的是,因为视图已经存在并且正在向用户显示,所以在获取数据时,您可以向用户显示一条漂亮的“等待”消息。

答案 1 :(得分:43)

viewDidLoad ===>>>将初始化代码放在这里。不要放置在视图生命周期中可能会更改的动态数据。因此,如果您从核心数据中提取数据,那么如果在视图的生命周期中这可能会发生变化,则您不希望在此处执行此操作。例如:假设你有一个标签控制器。您从tab1切换到tab2并在tab2中更改模型上的内容。如果你回到tab1并且你的模型代码是在viewDidLoad中完成的,那么就不会更新(假设你没有使用KVO或NSFetchedResultsController等)。

viewWillAppear ===>>>无论视图是否已在内存中,每次出现视图时都会调用此方法。将动态代码放在这里,例如模型逻辑。

viewDidAppear ===>>>如果您确定视图在屏幕上,例如网络呼叫,那么您只需要执行昂贵的操作。

注意:如果您的应用程序是后台运行并返回到前台,则需要使用NSNotificationCenter处理此问题。我在下面的评论中为此编写了代码。您可能会认为viewWillAppear / viewDidAppear将触发。在那里放一个断点并测试它。它不会开火。因此,如果您的应用在后台运行时发生了某些变化,则需要使用通知进行更新。

答案 2 :(得分:11)

在加载实际视图之前调用viewWillAppear方法。

在已加载视图时调用viewDidAppear方法,并且您想要显示某些内容。

答案 3 :(得分:8)

<强> viewWillAppear中:
■在将视图添加到窗口的视图层次结构之前调用 ■在[vc.view layoutSubviews]之前调用(如有必要)
 的 viewDidAppear
■视图添加到视图层次结构后调用 ■在[vc.view layoutSubviews]之后调用(如有必要)

答案 4 :(得分:5)

viewwillappear将在加载视图之前调用,以便您可以在加载视图之前执行某项任务,并且viewdidappear将在加载视图后调用,以便post任务将在该方法中完成

答案 5 :(得分:5)

一些观察结果:

  • 第一次实例化视图时,将调用viewDidLoad方法。 IBOutlet引用在调用时已连接,但不是在此之前。但是,视图的frame可能尚未建立。这是添加/配置子视图及其关联约束的好地方。但是,如果您要根据主视图的尺寸对frame值进行任何手动配置,则应将这些框架的配置推迟到viewWillAppearviewDidLayoutSubviews为止。

    < / li>
  • 当视图层次结构中的视图呈现即将开始时,将调用viewWillAppear方法。值得注意的是,这是在视图呈现的动画(如果有)的开始处调用的。从该视图开始过渡时,显然会调用其伴侣viewWillDisappear

  • 完成视图的呈现后,将调用viewDidAppear方法,尤其是在完成所有关联的动画之后。完成从该视图的过渡后,显然会调用其伴侣viewDidDisappear

两个重要警告:

    第一次实例化视图时,
  • viewDidLoad仅被调用一次。另一方面,viewWillAppearviewDidAppear不仅会在首次显示视图时被调用,而且在以后的每次相同视图中都会被重新显示。例如,当您首次显示视图时,将同时调用这三种方法。如果所讨论的视图随后显示另一个视图,随后又将其关闭,则在添加所讨论的视图并将其动画化回视图层次结构时,通常会再次调用viewWillAppearviewDidAppear,但是{{1 }} 将不会。 viewDidLoad仅在首次创建此特定实例时调用。

    因此,如果您希望每次重新显示视图时都执行某项操作(例如,关闭或弹出视图),请在viewDidLoadviewWillAppear中进行操作。如果希望仅在首次实例化视图时才发生,请在viewDidAppear中进行。

  • 调用viewDidLoad不能保证将完全完成向该视图的转换。值得注意的是,如果您使用的是由实时用户输入驱动的交互式转换,但是可以取消该交互式转换。即,仅因为viewWillAppear被调用,并不意味着viewWillAppear将被调用。通常是这样,但是如果取消了交互式笔势,则不会(因为过渡从未完成)。

    在WWDC 2013上,在交互式过渡的上下文中,演示者开玩笑说他们应该将viewDidAppear重命名为“ viewWillAppearviewMightAppearviewWillProbablyAppear”。 / p>

    一个内置交互手势的示例是使用iReallyWishThisViewWouldAppear时,您“从左边缘滑动”以启动视图弹出。 UINavigationController将被弹出的视图调用,但是如果您取消了“从左边缘滑动”以返回到您开始执行该弹出手势的视图,则会取消弹出操作,并且{ {1}}对于您开始弹出的视图将永远不会被调用。

    这样做的最终结果是,您应谨慎操作,不要编写假定每次对viewWillAppear的调用最终都会跟随对viewDidAppear的调用的代码。如果取消过渡,则情况并非如此。

答案 6 :(得分:4)

“will”和“did”之间的区别......顾名思义,在视图即将出现之前调用viewWillAppear,并在视图出现时调用viewDidAppear。

答案 7 :(得分:4)

1) ViewWillAppear :该视图实际上已加载到内存中,在视图控制器中被调用一次并具有其框架,但仍未显示给用户

2) ViewDidAppear :该控制器已添加到视图层次结构中,因此您可以将其呈现给下一个控制器, 而且,该视图确实布置了子视图

答案 8 :(得分:3)

前者在视图出现之前发生,后者在之后发生。

答案 9 :(得分:3)

总结一下:

-viewWillAppear - &gt;更新数据(从表格视图重新加载数据)

-viewDidAppear - &gt;昂贵的操作(具有良好进展的API调用!)

答案 10 :(得分:1)

顾名思义,在视图即将出现之前调用viewWillAppear,并在视图出现时调用viewDidAppear

答案 11 :(得分:0)

用例,即何时应使用哪个?

viewDidLoad-当标签,按钮(即任何控件/子视图)连接到View的界面文件时,并且如果要同时加载所有这些内容和ViewController的View,并且一次将其加载到内存中并完成操作

viewWillAppear-例如,您希望每次viewController出现在屏幕上时更改视图的背景颜色。或者更现实的是,如果您想在白天的夜晚使用DarkMode背景色,而在白天使用背景视图的浅色,请在viewWillAppear

中查找此代码

这里还有一个很好的用例 https://stackoverflow.com/a/39395865/5438240

还请注意,如果您使用的是导航堆栈(UINavigationController),则将要弹出的viewController将调用viewWillDisappear(),然后将在ViewController顶部堆栈将有viewWillAppear()被调用

答案 12 :(得分:0)

总的来说,这就是我所做的:

  1. ViewDidLoad - 每当我将控件添加到应该与视图一起出现的视图时,我立即将其放入 ViewDidLoad 方法中。基本上,只要将视图加载到内存中,就会调用此方法。例如,如果我的视图是一个带有 3 个标签的表单,我会在此处添加标签;没有这些形式,视图将永远存在。

  2. ViewWillAppear:我使用 ViewWillAppear 通常只是为了更新表单上的数据。因此,对于上面的示例,我将使用它来实际将我的域中的数据加载到表单中。创建 UIViews 是相当昂贵的,你应该尽可能避免在 ViewWillAppear 方法上这样做,因为当它被调用时,这意味着 iPhone 已经准备好向用户显示 UIView,以及你在这里做的任何繁重的事情将以非常明显的方式影响性能(例如动画被延迟等)。

  3. ViewDidAppear:最后,我使用 ViewDidAppear 来启动新线程来处理需要很长时间执行的事情,例如执行 Web 服务调用以获取上述表单的额外数据。好处是因为视图已经存在并且正在向用户显示,所以您可以在获取数据的同时向用户显示一个很好的“等待”消息。

答案 13 :(得分:0)

viewDidLoad - 当特定的视图控制器类加载到内存中时调用此函数。使用此方法,您可以对从 storyboard/nib 文件加载的视图执行额外的初始化。

ViewWillAppear - 通知并执行与显示视图相关的自定义任务。

ViewDidApper - 执行与呈现视图相关的其他任务。如果覆盖此方法,则必须在实现中的某个时刻调用 super。