- viewWillAppear: 和-viewDidAppear: 之间的区别是什么?

-[UIViewController viewWillAppear:]-[UIViewController viewDidAppear:]有什么不同?

81699 次浏览

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

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

Viewwill 出现将在加载视图之前调用,以便您可以在加载该视图之前完成某些任务,而 viewdid 出现将在加载该视图之后调用,因此后期任务将在该方法中完成

总的来说,我是这么做的:

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

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

  3. ViewDidAppear : 最后,我使用 ViewDidAppear开始执行需要很长时间才能执行的新线程,比如执行 Web 服务调用以获取上面表单的额外数据。好的一面是,因为视图已经存在并且正在显示给用户,所以在获取数据时可以向用户显示一个漂亮的“等待”消息。

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

当视图已经加载并且您希望显示某些内容时,将调用 viewDidAppear方法。

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

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

不管视图是否已经在内存中,每次视图即将出现时都会调用这个函数。将动态代码放在这里,例如模型逻辑。

将只有在确定视图显示在屏幕上时才需要执行的代价高昂的操作放在这里,比如网络调用。

注意: 如果您的应用程序是后台的,并返回到前台,您需要使用 NSNotificationCenter 处理此问题。我在下面的注释中写出了相应的代码。你可能会认为 viewWillAppear/viewDidAppear 会开火。在那里放一个断点,然后测试一下。不会开火。因此,如果你的应用程序在后台发生了变化,你需要使用通知来更新它。

返回文章页面出现:
在将视图添加到窗口的视图层次结构之前调用
■ 在[ vc.view layoutSubviews ]之前调用(如果需要)
显示 :
■ 在视图被添加到视图层次结构之后调用
■ 在[ vc.view layoutSubviews ]之后调用(如果需要)

总而言之:

- viewWillAppear-> update data (从表视图重新加载数据)

- viewDidAppear-> 昂贵的操作(具有良好进度的 API 调用!)

1) 视图显示: 实际装载在内存中的视图,在视图控制器中调用一次,并且有它的帧,但是仍然没有出现在用户面前

2) 视图出现: 添加到视图层次结构中的控制器,这样你就可以向下一个控制器显示, 此外,视图还对子视图进行了布局

以下是一些观察结果:

  • 首次实例化视图时调用 viewDidLoad方法。IBOutlet引用在被调用之前挂接起来,而不是在调用之前挂接起来。但是,视图的 frame可能不会在调用该视图时建立起来。这是添加/配置子视图及其相关约束的好地方。但是,如果您正在做任何基于主视图尺寸的 frame值的手动配置,那么这些帧的配置应该推迟到 viewWillAppearviewDidLayoutSubviews

  • 当视图层次结构中的视图表示即将开始时调用 viewWillAppear方法。值得注意的是,这在视图表示的动画(如果有的话)开始时被调用。当从这个视图开始转换时,它的同伴 viewWillDisappear被明显地调用。

  • 当视图的表示完成时,特别是当任何和所有相关的动画完成时,就会调用 viewDidAppear方法。它的同伴 viewDidDisappear在完成从这个视图的转换时被明显地调用。

两个重要的警告:

  • 第一次实例化视图时,只调用 viewDidLoad一次。另一方面,viewWillAppearviewDidAppear不仅在视图首次呈现时被调用,而且在随后的每一次相同的视图被重新呈现时也被调用。例如,当您首次呈现视图时,将调用所有这三个方法。如果有问题的视图随后提出了另一个视图,随后被解散,当有问题的视图被添加和动画回到视图层次结构时,通常会再次调用 viewWillAppearviewDidAppear,但是 viewDidLoad不会。只有在首次创建此特定实例时才调用 viewDidLoad

    所以,如果你想在每次视图重新出现的时候做一些事情(例如,你忽略或者弹回它) ,那么在 viewWillAppear或者 viewDidAppear中做。如果您希望它只在视图首次实例化时发生,那么在 viewDidLoad中执行此操作。

  • 调用 viewWillAppear并不能保证向该视图的转换将永远完成。值得注意的是,如果您正在使用由实时用户输入驱动的交互式转换,但是该交互式转换可以被取消。也就是说,仅仅因为 viewWillAppear被调用,并不意味着 viewDidAppear将被调用。一般来说是这样的,但是如果交互手势被取消,它就不会(因为转换从未完成)。

    在2013年全球开发者大会上,在互动过渡的背景下,一位主持人开玩笑说,他们应该把 viewWillAppear重命名为“ viewMightAppear,或者 viewWillProbablyAppear,或者 iReallyWishThisViewWouldAppear”。

    内置交互式手势的一个例子是当使用 UINavigationController时,你“从左边滑动”来启动视图的弹出。对于你弹出的视图,会调用 viewWillAppear,但是如果你取消“从左边滑动”返回到你开始弹出的视图,弹出将被取消,而对于你开始弹出的视图,viewDidAppear将永远不会被调用。

    这样做的最终结果是,您应该注意不要编写假设每次调用 viewWillAppear之后最终都会调用 viewDidAppear的代码。如果交接被取消,情况就不会是这样了。

用例 ,即 < strong > 什么时候应该使用哪个?

viewDidLoad-当标签,按钮(i,e 任何控件/子视图)连接到视图的接口文件,如果你想加载所有这些在同一时间作为视图控制器的视图,如果你想加载到内存一次,并完成它

比如,你想在每次 viewController 出现在屏幕上的时候改变视图的背景颜色。或者更实际,如果你想要暗模式的背景颜色在夜间的一天,和浅色的背景视图在白天的时间,去为这个代码在 viewWillAppear

这是另一个很好的案例 Https://stackoverflow.com/a/39395865/5438240

还要注意,如果您使用的是导航堆栈(UINavigationController) ,那么即将弹出的 viewController 将调用 viewWillDisappear(),接下来位于堆栈顶部的 ViewController 将调用 viewWillAppear()

总的来说,我是这么做的:

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

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

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

ViewDidLoad -当一个特定的视图控制器类加载到内存中时调用这个函数。使用此方法,您可以对从故事板/提示符文件加载的视图执行额外的初始化。

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

ViewDidApper -执行与显示视图相关的附加任务。如果重写此方法,则必须在实现中的某个位置调用 super。