UIViewController viewDidLoad与viewWillAppear:正确的分工是什么?


164

我一直对应分配给的任务类型有点不清楚viewDidLoad对比viewWillAppear:在一个UIViewController子类。

例如,我正在做一个应用程序,其中有一个UIViewController子类访问服务器,获取数据,将其提供给视图,然后显示该视图。在viewDidLoadvs. 中这样做的利弊是什么viewWillAppear

Answers:


251

viewDidLoad是您必须做一次的事情。每当出现视图时,都会调用viewWillAppear。您应该做的事情只需要在viewDidLoad中执行一次即可,例如设置UILabel文本。但是,您可能希望每次用户查看时都修改视图的特定部分,例如,每次进入“正在播放”视图时,iPod应用程序都会将歌词滚动回到顶部。

但是,从服务器加载内容时,还必须考虑延迟。如果将所有网络通信打包到viewDidLoad或viewWillAppear中,它们将在用户看到视图之前执行-可能会导致您的应用短暂冻结。首先向用户显示带有某种活动指示符的未填充视图可能是个好主意。完成网络连接后,这可能需要一到两秒钟(甚至可能会失败-谁知道?),因此可以用数据填充视图。可以在各种Twitter客户中看到有关如何完成此操作的好示例。例如,当您在Twitterrific中查看作者详细信息页面时,该视图仅显示“正在加载...”,直到完成网络查询为止。


因此,对于viewWillAppear可能被重复调用。例如,如果viewcontrollers视图在隐藏后变为可见(我是在这里闭塞,而不是UIView上的隐藏方法),该方法是否会触发?在哪个viewrio中将调用viewWillAppear而不先调用viewDidLoad?
dugla

7
仅在构造视图时调用viewDidLoad,例如,在访问视图时,例如在视图控制器initFromNibNamed调用之后。每当您的视图控制器不在视图中但进入视图时,都会调用viewWillAppear-因此,当推入视图控制器时,将调用viewWillAppear。如果从那里推送另一个子视图,并且用户返回,则将再次调用viewWillAppear。
Kendall Helmstetter Gelner,2009年

谢谢肯德尔。是的,有一些战略性放置的NSLogs使我感到头疼。viewWillAppear / viewWillDissappear在viewcontroller推送/弹出窗口上触发。
dugla

3
请注意,如果视图是隐藏的,并且由于与内存相关的原因而被卸载,则viewDidLoad也将被调用,然后重新出现。您可以依靠的是:首次创建视图时,viewDidLoad会被称为ATLEAST ONCE,而被隐藏后再次出现时,可能会被调用更多次。当视图即将出现在屏幕上时,总是会调用viewWillAppear。
DanM 2013年

2
有人可以进一步对这两个相关问题发表评论吗:(1)有时,并非总是如此,控件的帧值(即原点和大小)在viewDidLoad中为零,有时却不是-为什么?(2)在Apple的splitViewController的detailView(iPad)模板中,有一个configureView方法-相对于viewDidLoad和ViewWillAppear应该在里面做什么?
杰夫

12

最初仅将ViewDidLoad与tableView一起使用。在进行Wifi丢失测试时,通过将设备设置为飞行模式,意识到该表不会随着Wifi的返回而刷新。实际上,即使在-Info.plist中将背景模式设置为YES的情况下,按下主页按钮,似乎也无法刷新设备上的tableView。

我的解决方案:

-(void) viewWillAppear: (BOOL) animated { [self.tableView reloadData];}

10

重要的是要注意,使用viewDidLoad进行定位有些冒险,应避免使用,因为未设置边界。这可能会导致意外的结果(我遇到了很多问题...)

这篇文章很好地描述了不同的方法以及每种方法中发生的事情。

目前用于一次初始化和定位,我正在考虑将带标志的viewDidAppear使用,如果有人有其他建议,请告诉我。


对此表示同意:“ ...应避免使用,因为未设置界限...”
danisupr4

4

取决于,每次打开视图时是否需要加载数据?还是只有一次

在此处输入图片说明

  • 红色:他们不需要每次都更改。加载后,它们将保持原样。
  • 紫色:它们需要随着时间的推移或每次加载后进行更改。您不想看到相同的3个建议用户,每次您回到屏幕时都需要重新加载。他们的照片可能会更新...您不想看到5年前的照片...

viewDidLoad:无论您进行任何处理,都必须执行一次。
viewWilLAppear:每次加载页面时需要更改的任何处理。

标签,图标,按钮标题或大多数dataInputedByDeveloper 通常不会更改。名称,照片,链接,按钮状态,列表(tableViews或collectionView的输入数组)或大多数dataInputedByUser 通常都会更改。


紫色将在viewDidAppear中而不是viewWillAppear中被调用
Alex Kornhauser 18/12/10

@AlexKornhauser您的意思是什么?我是说viewWillAppear您可以查询和查看最新的推文。viewDidAppear为时已晚
亲爱的,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.