iOS 学习心得记录之:拿到了ViewController就等于
iOS 开发心得记录之:拿到了ViewController就等于拿到了view
在学习开发 iOS 的时候,我有时候会常常心里比较堵。
一个是创建了一个iOS singleView 项目之后,直接点击运行。一个什么都没有的iOS应用就跑了起来。
在这个背后,到底隐藏了哪些大致的细节?
在启动一个啥设置都没有改的iOS应用的时候,我们根据配置知道了当前的 view是main.storyboard。 mian.storyboard 后面操作着的控制器是 ViewController。
![](https://img.haomeiwen.com/i2701794/425f20311b4d5122.png)
![](https://img.haomeiwen.com/i2701794/07dec8f61ebb6ee8.png)
默认不修改任何配置的情况下,xcode 会根据配置信息 info.plist 来启动视图的类型,并间接的找到视图的控制器,从而创建视图和视图控制器这一对好基友。
![](https://img.haomeiwen.com/i2701794/1c5037629b31f457.png)
如果我不想使用程序的默认配置,不想把viewcontroller作为默认控制器,也不想把main.storyboard作为默认视图,我要全部自己手动来写。该如何做呢?
是先删除控制器,还是先删除视图?
是视图绑定了控制器?还是控制绑定了视图?
如果是单向依赖绑定的,是删除控制器还是删除视图?
在ViewController代码里,没有看到任何和视图有关的指向或依赖关系(除了一个从UIView继承过来的一个view属性)。
但是在main.storyboard的source code 模式下,我们发现了一个配置信息表明了是main.storyboard主动和ViewController绑定的。
![](https://img.haomeiwen.com/i2701794/051f776619022fcb.png)
在此过程中,ViewController 压根就不知道 main.storyboard的存在。在程序启动的时候,可能是根据配置信息。main.storyboard 或主动或被动的被赋值到了ViewController 的 view 属性上。
现在,我不想使用main.storyboard 作为iOS默认的启动视图,也不想使用ViewController 作为默认的视图控制器。
于是修改了程序配置,把默认启动视图设置为空,把默认的 ViewController 控制器类文件删除。
![](https://img.haomeiwen.com/i2701794/7192f10cb2ef63d9.png)
![](https://img.haomeiwen.com/i2701794/9c4fb5bb977998d3.png)
现在添加自己的ViewController。
![](https://img.haomeiwen.com/i2701794/b9aa67327c572462.png)
现在ViewController有了,view视图怎么办?之前是使用的 main.storyboard 。是一个文件。现在没有了这个文件,是不是要接着继续在添加一个my.storyboard,并设置为启动视图,并把它的ViewController设置成当前的MyViewController ?
这样做当然是可以的,但是和程序一开始启动没有做任何配置的时候就没有区别了。
既然 MyController 里有一个从 UIView 继承来的 view,我们就用这个属性来设定我们的视图,看行不行。
由于没有配置系统默认启动的页面,也就是第一次启动的页面。所以我们需要找一个合适的位置,也就是恰当的时机里,来设定我们的程序启动首视图。
在上一篇文章里,AppDelegate 就是为整个iOS程序生命周期关键时刻提供事件响应函数实现的对象。所以,很自然的,就找到了这个类的.m文件里。
![](https://img.haomeiwen.com/i2701794/e25e8970d6ceb5d3.png)
didFinishLaunchingWithOptions:在程序使用配置信息启动完成之后,这应该就是一个很合适的位置。
代码如下:
![](https://img.haomeiwen.com/i2701794/d4a87f841dcfdb30.png)
图中标有代码标记,会根据标记一行行的说明并提出问题。
1、标记为1的代码。
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
看了很多视频和一些书籍,也没有说出个所以然来。
下面说说我个人的理解:
假设问题:在默认情况下,我们没有修改任何 iOS singleview 项目模板的配置信息。那么是否在默认的情况下,UIApplication 会默认帮助我们创建一个和当前屏幕一样大的 UIWindow 对象呢?
回答:应该是的。应为默认的 iOS 项目可以正常启动,但如果自定义自己的修改了默认设定,启用自己的 ViewController ,不写这句代码就会出现程序报错。
结论:所有的 iOS 程序都要有一个 UIWindow 主容器,不管是生命周期哪个时机创建,也不管是系统自身根据默认配置还是自己手动创建。但一定要有一个。
2、标记为2的代码
MyViewController *myController = [[MyViewController alloc] init];
很简单的一句初始化自定义控制器的代码。但它的目的是什么?
3、标记为3的代码
self.window.rootViewController = myController;
将当前window的根控制器设置成myController?rootViewController ? 那是不是还有普通的viewController 呢 ?
查看源代码,发现rootViewController 是 UIWindow 继承自 UIView 得到的。UIView 是一个视图 ,视图需要控制器。所以这个属性就代表了 UIWindow 的控制器就是我们自定义的控制器?
如果 window 就是 mycontroller 的操控的那个视图的吗? 通过测试发现并不是。
![](https://img.haomeiwen.com/i2701794/2b817fe5f69f2884.png)
既然 myController 的 view 不是操控 window 的,那么 window 拿到 myController 的目的是什么呢?
下面全是个人猜测:
- window 作为一个全局的容器控件,掌管着iOS运行过程中的所有UIView。
- window 掌管视图的方式不是直接拿到视图,而是通过 myController 间接的方式控制到了视图。
- 设置 window 的 rootViewController 属性可以通过 controller 间接的决定哪一个视图会最先的出现在iOS程序的启动屏幕上。
![](https://img.haomeiwen.com/i2701794/02458fccd3f8b0dd.png)
所以,现在猜测,window 只是为了拿到首选 ViewController 从而决定了首选的 view 是哪个。(因为 controller 和 view 存在一个强绑定关系)
现在又抛出了一个问题:MyViewController 的 view 是谁 ?
先暂时放下这个问题,回到 MyViewController 的 .m 文件里。
![](https://img.haomeiwen.com/i2701794/be2b6ee4197b3e86.png)
发现,即使我们没有手动的
self.view = [[UIView alloc] init];
MyViewController 的 view 也是存在的。
所以来一个不负责任的猜测:所有的 UIViewController 在实例化的时候,会自己自动的创建一个 UIView 对象。
如果猜测没错,那么给 view 设置一个背景色应该也没啥问题吧?
![](https://img.haomeiwen.com/i2701794/419fce277745b991.png)
view 没有 alloc init 却正确的配置上了颜色。
于是不负责任的得出了一个自己浅薄的学习心得:
在做iOS开发的时候,有了 ViewController 就自动有了对应的 view 。
把更多的精力专注在 controller 上,而不要在像以前那样纠结,view 是哪个。
拿到的 controller 就行了,view 就帮我们自动创建。
开始证明【只要拿到了controller就行,view 会自动帮我们创建】
创建一个新的 OtherViewController。
![](https://img.haomeiwen.com/i2701794/338aa767c9783922.png)
在主界面添加一个按钮跳转到这个otherController。
![](https://img.haomeiwen.com/i2701794/4e2aa5cc5fb38ea6.png)
![](https://img.haomeiwen.com/i2701794/850ed72af0ab33c1.png)
“第一个 view 可能是因为在 iOS启动的初始阶段,iOS 启动框架有可能帮我们实例化了一个 view ,而其他的普通启动启动的 view 则需要我们自己创建 view 实例的推论就不言自破了。”
拿到了 controller 就行了,view 的创建会有 iOS 框架帮我们创建。
ps:上述全是本人在自学过程中的心得体会,可能有错误的地方,只作为同样在学习中的朋友一起探讨学习。不作为参考资料。