【问题标题】:Who should call viewDidLoad on programmatically loaded views?谁应该在以编程方式加载的视图上调用 viewDidLoad?
【发布时间】:2009-05-23 19:36:15
【问题描述】:

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

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。这是正确的方法还是我错过了什么?

【问题讨论】:

    标签: iphone cocoa-touch


    【解决方案1】:

    我是 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: 函数定义上方的 cmets 中写入的内容(包含在我的答案底部,请参见斜体字)。

    使用其中任何一种方法执行此操作的好处是,在任何一种情况下都会调用 viewDidLoad。

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

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

    【讨论】:

      【解决方案2】:

      你应该加载视图控制器

      MyController* myController = [[MyController alloc] initWithNibName:@"myNib" bundle:nil];
      

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

      【讨论】:

        【解决方案3】:

        视图由 UIViewController 延迟加载。如果您在代码中使用访问器myController.view,则应加载视图并调用viewDidLoad

        【讨论】:

        • 不,似乎也确实如此。加载的视图显示正常,但从未调用 viewDidLoad。我可以在调试器堆栈中看到,在从 nib 加载的“普通”控制器上,viewDidLoad 由 [UIViewController 视图] 调用,但似乎不适用于“手工制作”控制器。
        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多