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

PJR*_*PJR 130 iphone ios

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

Che*_*ara 289

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

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

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

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

  • 抱歉,你在`viewWillAppear`中"将我的域中的数据加载到表单中"是什么意思?你的意思是通过网络下载?但你也建议在`viewDidAppear`下载东西? (4认同)
  • 这个答案应该在文档中.这有助于澄清这三种方法之间的区别.谢谢! (2认同)

smi*_*Bot 46

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

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

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

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

  • @Jeef这是一个很好的问题.除非应用程序在后台被系统或用户杀死,否则都不会运行.如果应用程序处于非最小化状态,您必须执行以下操作才能使用NSNotificationCenter和addObserver作为名称UIApplicationWillEnterForegroundNotification.选择器应该是applicationWillEnterForeground:它有一个NSNotification参数.将您的代码放在该方法中以重新加载数据等.您可以做的是创建一个您从此方法调用的重载方法,如果它们需要相同,也可以调用viewDidAppear. (2认同)
  • @Jeef是这样的: - (void)viewDidLoad {[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground :) name:UIApplicationWillEnterForegroundNotification object:nil]; } - (void)applicationWillEnterForeground:(NSNotification*)notif {//在这里回复什么} (2认同)

pun*_*ria 12

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

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

  • 不正确的单词`loaded`.正确的是`出现' (11认同)

and*_*qee 8

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


dks*_*725 5

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


Abu*_*eid 5

1) ViewWillAppear:实际加载到内存中的视图,在视图控制器中调用一次并拥有其框架,但仍然没有向用户显示

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


Rob*_*Rob 5

一些观察:

  • viewDidLoad首次实例化视图时调用该方法.IBOutlet引用被调用的时间连接起来,但不是之前.但是frame,在调用此视图时,可能无法建立视图.这是添加/配置子视图及其相关约束的好地方.但是,如果您frame根据主视图的尺寸进行任何手动配置值,则应将这些帧的配置推迟到viewWillAppearviewDidLayoutSubviews.

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

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

两个重要的警告:

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

    所以,如果你想在每次视图重新出现时做某事(例如你解雇或弹回),请在viewWillAppear或中执行viewDidAppear.如果您希望它仅在首次实例化视图时发生,请执行此操作viewDidLoad.

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

    在WWDC 2013上,在交互式过渡的背景下,主持人开玩笑说他们应该重命名viewWillAppear为" viewMightAppear,或viewWillProbablyAppear,或iReallyWishThisViewWouldAppear".

    内置交互式手势的一个示例是使用a UINavigationController并且"从左边缘轻扫"以启动视图的弹出.该viewWillAppear会呼吁给你如雨后春笋般冒出的观点,但如果取消,"从左侧边缘滑动"要返回从中启动此弹出的姿态来看,在弹出被取消,viewDidAppear该视图你开始回弹永远不会被召唤.

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