NS for iOS Devs —查看生命周期

Swift Post 上以更好的格式阅读此文章

在学习了应用程序生命周期之后,视图生命周期在每个iOS开发人员的生命中都占有重要地位。

每个视图都是使用情节提要,XIB或编程方式创建的。 与方法无关,真正了解创建,加载,出现或销毁视图的时间有助于我们在开发屏幕设计,动画甚至业务逻辑时深刻理解我们的方法。

好的,但是为什么我们需要知道?

当我们考虑应用程序的生命周期时,我们很容易看到,随着应用程序进入后台,挂起等状态,某些事情正在发生。每当用户与应用程序进行交互时,就会发生某些特定的操作,并且应用程序的状态可能会发生变化。 但是,视图的状态可能会随着用户交互或应用程序数据的任何变化而改变。

另一方面,当视图中存在某种状态转换时,我们可能需要操纵用户界面。 例如,如果我们要使用自定义视图并将其设置为UIViewController的视图,则必须在loadView方法中进行操作。 或者,如果我们的设计要求我们在横向和纵向模式之间有微小的差异,那么我们需要知道何时可以在代码中进行此更改。 因此,了解所有生命周期方法不仅可以帮助我们编写代码,还可以使我们更具创造力并实现高级用户界面。

我们需要知道些什么?

为了在适当的位置使用视图,我们需要知道何时创建,加载,显示,更改,消失和终止视图。 UIViewController子类负责管理视图(又称UIView )。 视图控制器具有一个根视图,它是一个UIView实例。 这里重要的是它们如何一起工作。

UIViewController处理UIView背后的所有魔力,而UIView只是向用户显示屏幕和某些内容。 UIViewController告诉根UIView对象何时进入屏幕。 首先,视图控制器创建其根视图并加载它。 加载后,它告诉视图出现在屏幕上,并在必要时消失。

此外,一个视图控制器可能是另一个视图控制器的子代。 因此,视图控制器的生命周期不仅关心其根视图,而且还包括与其他视图控制器的关系,就像它是否移至父视图控制器一样。

最后,视图控制器的根视图(也称为UIView)具有自己的内容和生命周期。 根视图具有其子视图,例如按钮,标签,开关或其他UIView子类。 在大多数情况下,并不是每个开发人员都考虑子视图的生命周期。 但是有一种常见的情况是将视图控制器嵌入另一种情况。 在这种情况下,我们需要为两个视图控制器的视图模仿生命周期操作,并在必要时调用适当的方法。

我们如何获得有关生命周期事件的通知?

UIViewController有很多方法可以在发生某些特定操作时通知我们。 例如,我们可以重写viewDidLoad方法以在加载视图后立即执行一些操作。 或使用loadView方法将UIViewController的根UIView替换为我们的自定义UIView类。

我们将研究视图和视图控制器的组合之间的关系,以了解当前状态。 与其过多地关注每种方法的作用,不如介绍每种方法的重要意义以及何时使用它们。

UIView — UIViewController关系

  • loadView :这是加载视图控制器的根视图的位置。 viewUIViewController view属性为nil

如果要创建自定义视图并将其设置为view属性,则需要重写此方法。 如果使用Interface Builder创建视图和初始化视图控制器,则不得重写此方法。 重写此方法后,我们必须初始化自定义视图并将其设置为UIViewController view属性,并且永远不要调用super.loadView因为它自己创建视图并分配给view 。 最后,我们不应该直接调用此方法。

  • viewDidLoad :创建视图并将其加载到内存后,仅调用一次。 但是视图的bounds尚未定义。 通常,我们重写此方法来初始化视图控制器将使用的对象。 覆盖时,我们不应忘记调用super。
  • viewWillAppear(_:) :在视图出现在屏幕上之前立即调用此方法。 调用此方法时,定义了视图的边界,但尚未设置方向。 我们在使用外观方法时需要小心,因为每次视图进入屏幕时都会调用它们。 同样,我们不应忘记将其称为super。
  • viewDidAppear(_:) :在用户看到视图后立即调用此方法。 这是开始动画的好地方。 和以前一样,我们不要忘记调用super。
  • viewWillLayoutSubviews :这是了解生命周期中视图范围的第一处。 在UIView触发layoutSubviews方法之前,也将调用此方法。 加载根视图的子视图时,也会调用此方法。 例如; 加载收集视图的单元格时调用此方法。
  • viewDidLayoutSubviews :在调用layoutSubviews之后立即调用它。 设置了子视图,并应用了大小,位置和约束。

当屏幕的方向在纵向和横向模式之间更改时,也会调用viewWillLayoutSubviewsviewDidLayoutSubviews 。 因此,关键是,每当更新视图范围或重新计算视图布局时,都会调用这两种方法。 同样,我们也不应忘记在这些方法中的某些时候调用super。

  • viewWillDisappear(_:) :当视图即将从屏幕上消失时调用此方法。 我们在这里可以做的一件事是保存用户数据,而不丢失任何重要信息。 另一件事,我们可能正在取消网络请求。 如果我们希望在视图消失时将第一响应者作业移交给另一个视图,也可以重写此方法。
  • viewDidDisappear(_:) :当视图从屏幕上消失时viewDidDisappear(_:)此方法。 目前,该视图已从视图层次结构中删除。

我们看了最常见的关系,视图和视图控制器关系,这也是UIKit实现的默认关系。 但是视图控制器不仅与视图建立了关系,而且还与其他视图控制器(如子代和父代)建立了关系。

UIViewController — UIViewController关系

如果我们将一个视图控制器嵌入另一个视图控制器,那么了解视图控制器的这种关系和生命周期就很重要。 因为我们可能需要手动调用一些生命周期方法来通知系统有关状态。 让我们举一个添加和删除子视图控制器的示例。

让我们检查一下我们在生命周期方面正在做什么。 创建视图控制器后,我们将子级添加到父级。 此添加会自动为我们调用childViewController.willMove(toParent: parentViewController) 。 因此,我们不需要手动调用它。 然后,我们需要将子视图控制器的视图添加到父视图,以使视图具有子-父关系。 系统将加载两个视图,并通过调用addSubview将一个视图添加到另一个视图。 然后,我们通过调用didMove(toParent:)通知系统,然后系统将处理其余部分以显示视图控制器,并在其生命周期中调用视图控制器的必要方法,例如viewDidLoadviewDidAppear等。

另一方面,在从父级中删除子级视图控制器时,我们必须使用nil调用willMove(toParent:)方法,以通知系统有关将从父级中删除子级视图控制器的信息。 然后,我们从父级中删除其视图,然后删除其自身。 如我们所见,我们在删除它时不需要调用didMove(toParent:)方法。 removeFromParent方法会自动为我们调用该方法。

此外,我们可以覆盖willMove(toParent:)didMove(toParent:) 。 如果我们需要在视图控制器中知道它已作为子项添加到另一个视图控制器中,则可以覆盖这些方法并实现我们的自定义操作。

父子视图控制器关系很常见。 了解两个视图控制器的生命周期很重要,以便在某个时刻调用必要的方法。 如果我们忘记调用一种方法,则可能导致应用程序内部出现一些内存问题。 现在,我们到了最后一点-视图及其子视图与生命周期方法之间的关系。

视图—视图(子视图)关系

在这种关系中,大多数生命周期都是由系统自动处理的,不需要调用某些方法,例如父视图视图控制器和子视图控制器关系。 例如,即使我们尝试调用willRemoveSubview方法,它也不会执行任何操作。 默认实现为空。 系统调用以下功能仅是在发生更改时通知我们。 没有太多要谈论的事情。 了解到我们有地方可以检测到何时添加了子视图,或者该视图被添加为子视图或移至窗口,这为在这些阶段中执行额外操作提供了机会。

这里是提到的UIView生命周期方法:

  • didAddSubview(_:)
  • willRemoveSubview(_:)
  • willMove(toSuperView:)
  • didMoveToSuperview
  • willMove(toWindow:)
  • didMoveToWindow

在这里仅要导入的内容是removeFromSuperview方法。 如果我们要从其父视图中删除视图,则可以调用此方法。 调用此方法将删除视图及其子树中的所有约束。 我们不应该在视图的draw(_:)方法内调用此方法。

仅了解应用程序之一,视图控制器,视图生命周期还不足以了解整个图片并全面了解iOS应用程序。 掌握生命周期方法的使用对于在某些地方采取适当的操作非常重要,尤其是使用UIKit类的自定义实现时。 现在我们知道了生命周期,我们可以真正了解系统幕后发生的事情,并在必要时进行干预。

在使用视图生命周期时,您遵循哪些策略? 您如何看待视图和视图控制器关系的重要性? 苹果公司应该给予更大的自由来操纵生命周期,还是您找到一些变通办法来实现这种愿望? 在Twitter @candostEN上告诉您您的想法,评论或反馈。


NS for iOS Devs Series的所有帖子

  • 应用生命周期
  • 查看生命周期
  • 并发
  • 可测性

进一步:

视图的生命周期

UIViewController文档

实施容器视图控制器