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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5630649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:32:52  来源:igfitidea点击:

What is the difference between -viewWillAppear: and -viewDidAppear:?

iphoneios

提问by PJR

What is the difference between -[UIViewController viewWillAppear:]and -[UIViewController viewDidAppear:]?

-[UIViewController viewWillAppear:]和 和有-[UIViewController viewDidAppear:]什么区别?

回答by Chetan Bhalara

In general, this is what I do:

一般来说,这就是我所做的:

1) ViewDidLoad- Whenever I'm adding controls to a view that should appear together with the view, right away, I put it in the ViewDidLoad method. Basically this method is called whenever the view was loaded into memory. So for example, if my view is a form with 3 labels, I would add the labels here; the view will never exist without those forms.

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

2) ViewWillAppear: I use ViewWillAppear usually just to update the data on the form. So, for the example above, I would use this to actually load the data from my domain into the form. Creation of UIViews is fairly expensive, and you should avoid as much as possible doing that on the ViewWillAppear method, becuase when this gets called, it means that the iPhone is already ready to show the UIView to the user, and anything heavy you do here will impact performance in a very visible manner (like animations being delayed, etc).

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

3) ViewDidAppear: Finally, I use the ViewDidAppear to start off new threads to things that would take a long time to execute, like for example doing a webservice call to get extra data for the form above.The good thing is that because the view already exists and is being displayed to the user, you can show a nice "Waiting" message to the user while you get the data.

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

回答by smileBot

viewDidLoad===>>> Put your initialization code here. Don't put dynamic data that might change during the view lifecycle. So, if you are pulling data from core data you don't want to do it here if this could change during the life of the view. For example: say you have a tab controller. You switch from tab1 to tab2 and change something on the model in tab2. If you come back to tab1 and your model code was done in viewDidLoad this would not be updated (assuming you're not using KVO or NSFetchedResultsController, etc.).

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

viewWillAppear===>>> This is called every time the view is about to appear, whether or not the view is already in memory. Put your dynamic code here, such as model logic.

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

viewDidAppear===>>> Put expensive operations here that you only want to do if you're sure the view is onscreen, such as network calls.

viewDidAppear===>>> 将昂贵的操作放在这里,如果您确定视图在屏幕上,您才想要执行这些操作,例如网络调用。

Notice: if your app is backgrounded and returns to the foreground you need to handle this using NSNotificationCenter. I wrote the code out for that in the comments below. You might think viewWillAppear/viewDidAppear will fire. Put a break point there and test it. It doesn't fire. So, if something has changed for your app while it was in the background you'll need to update that using notifications.

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

回答by puneet kathuria

The viewWillAppearmethod is called before loading the actual view.

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

The viewDidAppearmethod is called when the view is already loaded, and you want to show something.

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

回答by andyqee

viewWillAppear:
■ Called before the view is added to the windows' view hierarchy
■ Called before [vc.view layoutSubviews] (if necessary)
viewDidAppear:
■ Called after the view is added to the view hierarchy
■ Called after [vc.view layoutSubviews] (if necessary)

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

回答by Rob

A few observations:

一些观察:

  • The viewDidLoadmethod is called when the view is first instantiated. IBOutletreferences are hooked up by the time this has been called, but not before. The frameof the view may not be established by the time this has been called, though. This is a great place to add/configure subviews and their associated constraints. But if you are doing any manual configuration of framevalues on the basis of the main view's dimensions, the configuration of those frames should be deferred until viewWillAppearor viewDidLayoutSubviews.

  • The viewWillAppearmethod is called when the presentation of the view in the view hierarchy is about to start. Notably, this is called at the start of the animation (if any) of the presentation of the view. Its companion, viewWillDisappearis obviously called when the transition away from this view begins.

  • The viewDidAppearmethod is called when the presentation of the view is done, notably when any and all associated animation has finished. Its companion, viewDidDisappearis obviously called when the transition away from this view is done.

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

  • viewWillAppear当视图层次结构中的视图呈现即将开始时调用该方法。值得注意的是,这在视图呈现的动画(如果有)开始时调用。它的同伴,viewWillDisappear显然是在远离这个视图的过渡开始时被调用的。

  • viewDidAppear当视图的呈现完成时调用该方法,特别是当任何和所有关联的动画都完成时。它的伴生,viewDidDisappear显然是在离开这个视图的过渡完成时被调用的。

Two important caveats:

两个重要的警告:

  • viewDidLoadis called once and only once, when the view is first instantiated. On the other hand, viewWillAppearand viewDidAppearwill be called not only when the view is first presented, but every subsequent time the same view in question is re-presented. For example, when you first present a view, all three of these methods will be called. If the view in question subsequently presents another view which is subsequently dismissed, the viewWillAppearand viewDidAppearwill generally be called again when the view in question is added and animated back into the view hierarchy, but viewDidLoadwill not. viewDidLoadis only called when this particular instance is first created.

    So, if you want to do something every time a view reappears (e.g. you dismiss or pop back to it), do it in viewWillAppearor viewDidAppear. If you want it to only happen when the view is first instantiated, do that in viewDidLoad.

  • The calling of viewWillAppeardoes not guarantee that transition to that view will ever be completed. Notably, if you are using interactive transition that are driven by real-time user input, but that interactive transition can be canceled. I.e., just because viewWillAppearis called, it does not mean that viewDidAppearwill called. Generally it is, but if the interactive gesture is cancelled, it won't (because the transition never finished).

    At WWDC 2013, in the context of interactive transitions, a presenter joked that they should rename viewWillAppearto "viewMightAppear, or viewWillProbablyAppear, or iReallyWishThisViewWouldAppear".

    An example of a built-in interactive gesture is when using a UINavigationControllerand you "swipe from the left edge" to initiate a pop of the view. The viewWillAppearwill be called for the view to which you are popping, but if you cancel that "swipe from left edge" to return back to the view from which you started this pop gesture, the pop is canceled and the viewDidAppearfor the view you started to pop back to will never be called.

    The net effect of this is that you should be careful that you don't write code that assumes that every call to viewWillAppearwill be followed eventually by a call to viewDidAppear. If the transition is canceled, this will not be the case.

  • viewDidLoad在第一次实例化视图时调用一次且仅一次。另一方面,viewWillAppearandviewDidAppear不仅会在第一次呈现视图时调用,而且每次都会重新呈现有问题的相同视图。例如,当您第一次展示一个视图时,这三个方法都会被调用。如果有问题的观点随后呈现随后被解雇时,另一种观点认为viewWillAppear,并viewDidAppear在有问题的视图添加和动画回视图层次一般会被再次调用,但viewDidLoad不会。viewDidLoad仅在首次创建此特定实例时调用。

    因此,如果您想在每次视图重新出现时执行某些操作(例如,您关闭或弹出该视图),请在viewWillAppear或 中执行viewDidAppear。如果您希望它仅在第一次实例化视图时发生,请在viewDidLoad.

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

    在 WWDC 2013 上,在交互式过渡的背景下,一位演示者开玩笑说他们应该重命名viewWillAppear为“ viewMightAppear,或viewWillProbablyAppear,或iReallyWishThisViewWouldAppear”。

    内置交互手势的一个示例是使用 aUINavigationController并且您“从左边缘滑动”以启动视图的弹出。该viewWillAppear会呼吁给你如雨后春笋般冒出的观点,但如果取消,“从左侧边缘滑动”,以返回到从中启动此弹出的姿态来看,在弹出被取消,viewDidAppear该视图你开始pop back to 永远不会被调用。

    这样做的最终结果是,您应该小心,不要编写假定每次调用 的代码viewWillAppear最终都会调用viewDidAppear. 如果转换被取消,则不会出现这种情况。

回答by dks1725

viewwillappear will call before loading the view so that you can do certain task before loading that view and viewdidappear will call after loading the view so the post task will done in that method

viewwillappear 将在加载视图之前调用,以便您可以在加载该视图之前执行某些任务,而 viewdidappear 将在加载视图后调用,因此发布任务将在该方法中完成

回答by Abuzeid Ibrahim

1) ViewWillAppear: The view loaded actually in the memory, called once in the view controller and had its frame, but still didn't appear to the user

1) ViewWillAppear:实际加载到内存中的视图,在视图控制器中调用一次并有它的框架,但仍然没有出现在用户面前

2) ViewDidAppear: The controller added to the view hierarchy, so you could present to the next controller, also, the view did layout the subviews

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

回答by Mahesh

Difference between "will" and "did"...As the name suggests the viewWillAppear is called before the view is about to appear and viewDidAppear is called when view did appear.

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

回答by Marc Abramowitz

The former happens before the view appears and the latter happens afterwards.

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

回答by Nahuel Roldan

To sum up:

总结:

-viewWillAppear -> update data (reload data from a table view)

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

-viewDidAppear -> expensive operations (API call with a nice progress hud!)

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