翻译关于ViewController的一篇文章

翻译苹果官网的文章一则

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html

 

初始化 ViewController

第一次实例化的时候,通过生命周期创建或者加载对象,它不应该创建view hierarchy 或者其他跟显示画面相关的内容,它应该关注对象,关注实现生命周期中特殊行为的对象。

 

初始化storyboard中加载的ViewController

当我们在storyboard中创建view controller时,配置的属性都会存储到一个配置信息文档中,之后当实例化时,文档就会被加载到内存和进程中去,结果就是会有一系列的符合之前配置信息的对象会生成,配置信息文档会被view controller的initwithcode:方法加载。这之后任何实现了awakeFromNib方法的对象调用这个方法。用这个方法配置信息。

 

用代码初始化ViewController

如果view controller用代码创建的,那么我们重写一下init方法,当然这个方法首先要调用父类的init方法,然后再加上自己的其他客户化的内容。

通常,实例化方法里面不要写过于复杂的方法,而是应该实现简单的功能,并且提供必要的属性给view controller的委托类从而配置它的行为。

 

ViewController 当访问VIEW属性时会实例化它的VIEW Hierarchy。

无论何时当你的app需要访问view,而view对象不在内存中时,view controller都会加载view hierarchy

进内存,并且存储在它的view属性内,循环加载的步骤如下:

1、view controller 调用自己的loadview方法。方法默认会实现下面的某一个内容:

* 如果view controller关联了一个storyboard,那么就从storyboard中加载。

* 如果没有关联的故事模板,那么会创建一个空的UIView对象,并且赋值给view属性。

2、view controller调用viewDidLoad方法,这能够确保你的子类能够执行额外的load-time任务。

下面的图示展示了view controller是如何循环加载的,包含了一些需要调用的方法。我们的app可以覆盖loadview方法和viewDidLoad方法。举个例子,如果你的app没有用storyboard,但是你却想增加一个view,这时可以覆盖loadview方法用代码初始化view。

下面这个图的标题是:向内存中加载view

 

 

从storyboard中加载一个view

 

大多数的view controller 从storyboard中加载他们的view,优点就是可以用可见的方式配置布局,这很容易也很快速。

在interface builder中创建view

interface builder是xcode的一部分,他可以给我们的viewcontroller提供方便的直观的方式去配置view的相关属性。在这里可以同时操控view和controller,控件直接拽到工作空间中,设置大小,属性等,设置完毕后直接存储在storyboard文件中。

 

在interface builder中配置view的图形属性

为了正确的展示内容布局,interface builder提供了控件可以让你去指定是否view有导航bar、工具bar等其他的对象,这些对象都可以影响你的定制内容。如果controller连接到容器中,也可以提供精确的运行时的显示效果。

 

为view controller配置Action和Outlet

利用IB,可以在view和controller之间建立连接。

下面的代码显示如何声明一个MyVIewController类的controller以及它的两个custom outlet 和一个 ibaciton方法。这个声明其实是在.m文件内的category。outlets存储了一个按钮和一个textfield引用。下面的方法则监听按钮的按下动作。

 

@interface MyViewController()

 

@property (nonatomic) IBOutlet id myButton;

 

@property (nonatomic) IBOutlet id myTextField;

 

 

 

- (IBAction)myAction:(id)sender;

 

@end

 

而下面的图示则展示了上面代码部分建立的对象之间的连接

 

 

接下来介绍一下代码的方式创建视图(view)//1️⃣

如果你更喜欢用代码来创建视图,应该覆盖你的view controller 的loadview方法,你的方法实现应该遵从以下的几点:

 

1、创建一个根视图对象。

根视图内包含所有跟view controller有关的所有视图,通常会给根视图定义一个frame去匹配app window的size,frame应该是布满整个屏幕的。然而frame会根据你的view controller来调整它的display1️⃣。这个根视图可以是普通的UIView,也可以是自己的客户化的view,或者任何其他可以铺满屏幕的view。

2、创建子视图并且加入到根视图内

对于每个子视图都应该创建并且初始化,然后用addSubview:方法加入到父视图中去。

3、如果用了自动旋转布局模式,应该给每个视图配置足够多的位置限定条件。并且还要实现两个方法:viewWillLayoutSubviews和viewDidLayoutSubview来调整子类的frame。

4、添加根视图到view controller的property中。

下面的代码展示了如何创建视图和子视图

- (void)loadView

 

{

 

    CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];

 

    UIView *contentView = [[UIView alloc] initWithFrame:applicationFrame];

 

    contentView.backgroundColor = [UIColor blackColor];

 

    self.view = contentView;

 

 

 

    levelView = [[LevelView alloc] initWithFrame:applicationFrame viewController:self];

 

    [self.view addSubview:levelView];

 

}

 

Note: When overriding the loadView method to create your views programmatically, you should not call super. Doing so initiates the default view-loading behavior and usually just wastes CPU cycles. Your own implementation of the loadView method should do all the work that is needed to create a root view and subviews for your view controller. For more information on the view loading process, see “A View Controller Instantiates Its View Hierarchy When Its View is Accessed.”

注意:用代码覆盖loadView方法去新建视图时,不可以调用super.初始化默认的view-loading行为,这通常会引起cpu的运行浪费。你自己的loadview方法的实现应该做所有需要的工作。

 

原文地址:https://www.cnblogs.com/qiqingnan/p/3764110.html