addChildViewController相关api深入剖析

简介: 注:本文根据个人的实践和理解写成,若有不当之处欢迎斧正和探讨!addChildViewController是一个从iOS5开始支持的api接口,相关的一系列的接口是用来处理viewcontroller中嵌套显示其他viewcontroller的场景的。

注:本文根据个人的实践和理解写成,若有不当之处欢迎斧正和探讨!


addChildViewController是一个从iOS5开始支持的api接口,相关的一系列的接口是用来处理viewcontroller中嵌套显示其他viewcontroller的场景的。

在出现此api之前,大家可能会使用addsubview并持有viewcontroller对象的方式来实现这个需求,控制多个viewcontroller的view的hidden标签达到同时只显示1个子viewcontroller和切换子viewcontroller的目的。

相关主要api一览:


1.- addChildViewController:

加入子viewcontroller。


2.- removeFromParentViewController

将自身从父viewcontroller中移除(脱离关系)


子viewcontroller切换示例:

   3.    [self transitionFromViewController:self.currentViewController
                          toViewController:selectedVC
                                  duration:0
                                   options:UIViewAnimationOptionTransitionNone
                                animations:nil
                                completion:nil];


4.willMoveToParentViewController:
5.didMoveToParentViewController:

6. 一个只读属性:childViewControllers , 可以用来获取此容器viewcontroller当前拥有的全部childviewcontroller。

其中1和2很容易理解;就是建立/解除viewcontroller之间的父子关系(注意:实际使用时还是要结合调用addsubview来把视图加进来)。
3:当1个容器viewcontroller中加入多个child时,使用该api来切换childviewcontroller,并可以设置动画效果和结束事件处理,很方便。

其中4和5就有些奇怪了,光从命名来看可能会以为是子viewcontroller即将隐藏和已经隐藏时触发的方法,但实际上我们阅读其api发现情况不是这样。

看下苹果官方文档:

willMoveToParentViewController:
Called just before the view controller is added or removed from a container view controller.

Discussion
Your view controller can override this method when it needs to know that it has been added to a container.

If you are implementing your own container view controller, it must call the willMoveToParentViewController: method of the child view controller before calling the removeFromParentViewController method, passing in a parent value of nil.

When your custom container calls the addChildViewController: method, it automatically calls the willMoveToParentViewController: method of the view controller to be added as a child before adding it.


didMoveToParentViewController:
Called after the view controller is added or removed from a container view controller.

Discussion
Your view controller can override this method when it wants to react to being added to a container.

If you are implementing your own container view controller, it must call the didMoveToParentViewController: method of the child view controller after the transition to the new controller is complete or, if there is no transition, immediately after calling the addChildViewController: method.

The removeFromParentViewController method automatically calls the didMoveToParentViewController: method of the child view controller after it removes the child.


这里如果暂时先不考虑“implementing your own container view controller”,看一下苹果实现的container view controller, 最典型的莫过于 navigationcontroller了。
那么我们这里可以联想一下,可能navigationcontroller相关的pop、push也是基于这一套api机制来实现的。
我们在demo里面打印通过navigationcontroller push出来的界面的生命周期方法(包括willMoveToParentViewController和didMoveToParentViewController),
我们发现:
界面push进来时:
willMoveToParentViewController
viewdidload
didMoveToParentViewController

界面退出时:
willMoveToParentViewController
didMoveToParentViewController
dealloc

再结合上面api的两句话:
willMoveToParentViewController:
Called just before the view controller is added or removed from a container view controller.  在viewcontroller被添加或者移除之前时被调用;
didMoveToParentViewController:
Called after the view controller is added or removed from a container view controller. 在viewcontroller被添加或者移除之后被调用。

再来看“implementing your own container view controller”时的情况,我们仅仅通过1、2、3来使用这一套api,那么实际测试发现当child被加入到parent的时候只会触发willMoveToParentViewController,而当child被移出parent的时候只触发了didMoveToParentViewController方法。

再仔细看下苹果api文档说明:
在“implementing your own container view controller”时,将自己从父viewcontroller移除之前,需要手动调用willMoveToParentViewController;
同样的,将自己加入父viewcontroller以后(或者从其他子viewcontroller页面迁移而来时)需要手动调用didMoveToParentViewController(时机在addchild或者迁移的completion结束以后)。


综上,我们可以分析知:willMoveToParentViewController、didMoveToParentViewController可以用来帮助我们进行一些页面跳转相关的生命周期业务逻辑处理,但其存在一些问题不可不察:
1.需要准确的理解这两个方法触发的时机
2.对于系统的container,这两个方法一定会在适当的时机触发;而对于自己实现的container,必须要在适当的时机手动调用这两个方法,才能保证其触发的完备性。如果你不手动调用,那么你也要准确的理解在这种场景下什么时候会触发
3.从一个开发者角度来说,我认为这两个api的设计比较失败。首先其命名并不能直观表达出其触发场景;且其使用上也有诸多限制。因此对于调用者来说,建议仅在不使用这两个api就无法满足业务需求时才使用这两个api。

最后:推荐一个国人的UI框架,写的很用心,其中addChildViewController相关api还有其他一些转场之类的api使用,可以作为很好的学习参考。 https://github.com/tianzhuo112/VTMagic







目录
相关文章
|
3月前
|
安全 API 网络安全
浅谈API安全
浅谈API安全
浅谈API安全
|
7月前
|
安全 API
常用API
常用API接口分享
61 0
|
7月前
|
API
7.3 通过API枚举进程
首先实现枚举当前系统中所有进程信息,枚举该进程的核心点在于使用`CreateToolhelp32Snapshot()`函数,该函数用于创建系统进程和线程快照,它可以捕获当前系统中进程和线程相关的信息(如PID、线程数量、线程ID等),在对这些信息进行处理后,可以获得很多有用的数据,如当前系统中所有正在执行的进程的信息列表,以及每个进程各自的详细信息(如CPU、内存占用量等)。
37 1
|
8月前
|
DataWorks API
CreateQualityRelativeNode API
CreateQualityRelativeNode API
40 1
|
9月前
|
数据采集 人工智能 JSON
这可能是我用过最“强大”的API
早前我也推荐过豆瓣的 API,不过豆瓣现已把开发者页面下线,无法查看具体接口说明,之后会不会对外关闭也很难说了。Marvel API 相比豆瓣 API 来说要复杂一些,主要是权限认证的部分。另外,在使用时还有一些要求
|
10月前
|
机器学习/深度学习 Unix Linux
为什么需要API,什么是api
为什么需要API,什么是api
|
10月前
|
XML 存储 缓存
什么是 API?
什么是 API?
|
10月前
|
SQL 缓存 Java
|
10月前
|
API 开发者
API是什么的,了解API
API是Application Programming Interface的缩写,用于描述一种用于不同软件组件之间相互通信和交互的标准方式。简单来说,API提供了一种可以让开发者利用现有的代码、工具和服务,将它们组合成新的应用程序或系统的方法。
162 0