谁应该在以编程方式加载的视图上调用viewDidLoad?

时间:2009-05-23 19:36:16

标签: iphone cocoa-touch

当我需要以编程方式加载视图时,我会执行以下操作:

MyController* myController = [[MyController alloc] init];
[[NSBundle mainBundle] loadNibNamed:@"myNib" owner:myController options:nil];
// use my controller here, eg. push it in the nav controller

这很好用,但我的控制器的viewDidLoad永远不会被调用。所以我在loadNibNamed调用之后尝试手动调用它,但它似乎不正确。我期待框架代表我调用viewDidLoad。这是正确的方式还是我错过了什么?

4 个答案:

答案 0 :(得分:5)

我是Stack Overflow的新手,但我发现了这个问题并发现了一些其他方法来加载一个nib文件,以确保自动调用viewDidLoad方法。 Ed Marty的回答是正确的,但它要求你在ViewController的代码之外加载nib文件,我在这里提供的这两个例子允许你将代码保存在ViewController的实现中。不一定是更好的方式,只是不同。如果你知道这样做的任何缺点,请告诉我你的想法。

首先,在UIViewController子类的initWithNibName:bundle:方法内,您可以替换调用:
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

有这样的事:
self = [super initWithNibName:@"NameOfAlternateNibFile" bundle:nibBundleOrNil];

或者,您可以通过以下方式完成看似完全相同的事情:

[[NSBundle mainBundle] loadNibNamed:@"NameOfAlternateNibFile" owner:self options:nil];
[self setView:self.view]; //this line ensures that the viewDidLoad method is called

关键在于理解UIViewController.h文件中$initWithNibName:bundle:的函数定义上面的注释中所写的内容(包含在我的答案底部,见斜体)。

使用这两种方法之一做这件事的好处是在任一场景中都会调用viewDidLoad。

以下是UIViewController.h中列出的指令:

  

指定的初始化程序。如果你   子类UIViewController,你必须   调用这个的超级实现   方法,即使你没有使用   笔尖。 (为方便起见,默认   init方法将为您完成此操作,并且   为这两种方法指定nil   参数。)在指定的NIB中,   文件的所有者代理应该有它的   class设置为视图控制器   子类,带视图出口   连接到主视图。如果你   使用nil nib调用此方法   name,然后这个类'-loadView   方法将尝试加载NIB   其名称与您的视图相同   控制器的类。如果没有这样的NIB   事实上存在 你必须要么   call -setView:before -view    调用 ,或覆盖-loadView方法以编程方式设置视图。    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;

答案 1 :(得分:3)

您应该使用

加载视图控制器
MyController* myController = [[MyController alloc] initWithNibName:@"myNib" bundle:nil];

确保您的MyController从UIViewController扩展,并且在Interface Builder中正确设置了View属性。

答案 2 :(得分:1)

UIViewController懒惰地加载视图。如果您在代码中使用访问者myController.view,则应加载视图并调用viewDidLoad

答案 3 :(得分:0)

我注意到了同样的事情。我认为ViewDidLoad必须由视图CONTROLLER调用。由于您的笔尖中没有视图控件,因此必须手动调用viewdidload。我必须做同样的事情。