【问题标题】:UIViewController -viewDidLoad not being calledUIViewController -viewDidLoad 没有被调用
【发布时间】:2010-10-29 03:45:06
【问题描述】:

作为 Cocoa 的新手,我在 Interface Builder、UIViewController 和朋友方面遇到了一些问题。

我有一个 UIViewController 子类,在 xib 中定义了 UIView,并且控制器的视图出口连接到视图。 xib 的“文件所有者”设置为 myViewcontroller 子类。

在这种情况下,以下用于加载控制器/视图(从主视图控制器)的代码无法按预期工作:

if ( self.myViewController == nil )
{
    self.myViewController = [[MyViewController alloc]
        initWithNibName:@"MyViewController" bundle:nil];
}

[self.navigationController 
    pushViewController:self.myViewController animated:YES];

在 MyViewController 的方法中,我放置了断点并记录消息以查看发生了什么:

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        NSLog(@"initWithNibName\n");
    }

    return self;
}

-(void)viewDidLoad {

    [super viewDidLoad];
    NSLog(@"viewDidLoad\n");
}

预期结果

-initWithNibName 和 -viewDidLoad 方法都被调用,并显示 myViewController 的视图。

观察结果

只调用-initWithNibName,不显示视图。

我错过了什么吗?任何人都可以推荐任何要检查的东西吗? (特别是在极其不透明的 Interface Builder 工具中)。

【问题讨论】:

标签: iphone cocoa-touch uiview uiviewcontroller


【解决方案1】:

RE:找到解决方案!!!!!

确实这似乎是一个可行的解决方案,但真正的技巧不是将view.hidden 属性设置为 NO,使视图从 nib 文件加载的原因是调用 UIViewController's 视图方法,视图只有在第一次调用 view 方法时才真正从 nib 加载。

从这个意义上说,一个简单的[viewController view] 消息将强制视图从 nib 文件加载。

【讨论】:

  • 最佳答案。 [viewController view]
  • 你拯救了我的一天。非常感谢。
  • (swift) 使用let _ = controller.view 确实为我触发了 viewDidLoad。谢谢。
【解决方案2】:

好的,我有一个部分答案 - 也许大师可以解释更多。问题是:

[self.navigationController pushViewController:myViewController animated:YES];

仔细观察,在这种情况下,self.navigationController 为 nil - 所以推送消息无处可去。

相反,如果我发送:

[self.view addSubview:self.myViewController.view];

然后视图出现并调用-viewDidLoad。

我不完全确定为什么在这种情况下没有设置 self.navigationController - 我唯一能想到的是 self 是 UIViewController 而不是 UITableViewController 的子类(其中 pushViewController代码来自)。

此外,静默允许消息变为 nil 似乎是个坏主意,尽管 these answers 另有说法。另请参阅我的问题here。

最终编辑:

下面的cmets中的答案,我已经实现了我实际追求的显示功能(假设myViewController是模态的)是:

[self presentModalViewController:myViewController animated:YES];

感谢大家的有益回复。

【讨论】:

  • 不要说无声无息,当你习惯它时你会一直使用它:-) 当你第一次开始时它肯定会很神秘。至于navigationController为什么是nil:是不是被初始化为一个UINavigationController的根视图控制器?如果没有,在你这样做之前你不能使用 pushViewController!
  • 我认为 Adam 正是在这里,确保您的视图在尝试获取其 navigationController 之前已正确放置到导航堆栈中。
【解决方案3】:

找到解决方案!!!!!!

即使是这样无害的事情也会导致 viewDidLoad 方法调用发生。

在alloc initWithNibName之后插入这个

viewController.view.hidden = NO; //calls viewDidLoad

【讨论】:

  • 那是因为每次您使用视图属性时,getter 和/或 setter 都会触发视图的加载。即使只是输入'self.view;'就足够了
  • 但可能不建议这样做,因为它会缩短整个延迟加载方案。
【解决方案4】:

确保 File's Owner(您的 viewController 子类)中的视图出口连接到实际视图(即您在屏幕上看到的用于构建 UI 的 480X320 画布)

【讨论】:

  • 是的,谢谢,确实如此 - 我在上面提到过,但只是仔细检查过。
【解决方案5】:

您可能没有将main.storyboard 中的假定ViewController 从Identity Inspector 链接到您创建的自定义class。您也许可以通过 segue 从其他视图控制器导航到该控制器,但 viewDidLoad()、viewWillAppear() 等中的任何一个都不会被执行。

【讨论】:

    【解决方案6】:

    简单使用

    - (void)viewDidAppear:(BOOL)animated{ 
            [super viewDidAppear:animated];
            //Your Code here
      }
    

    而不是 viewDidLoad 方法。

    【讨论】:

      【解决方案7】:

      另一个原因,回想起来有些明显:如果在代码中设置了viewController.view,则不会触发 viewDidLoad 事件。

      【讨论】:

        【解决方案8】:

        对我来说,这似乎是一个大写问题。在对 pushViewController 的调用中,您引用的是类 MyViewController 而不是属性 myViewController。

        【讨论】:

        • 我的错误只是将代码移动到 stackoverflow 时打错了 - 我现在正在解决这个问题。谢谢。
        【解决方案9】:

        检查您的运行日志是否有错误。几乎可以肯定的是,NIB 没有加载,因此应该有错误。最可能的原因是未能将其放入捆绑包中。查看您的“复制资源”构建阶段并确保实际复制了 XIB。为模拟器构建,然后进入构建目录并确保 NIB 在 .app 包中。

        【讨论】:

        • 所有优点,CompileXIB 被调用,MyViewController 处于复制资源阶段并出现在应用程序包中。用干净的构建检查了几次。我还修改了 -initWithNibName NSLog 以写入 'self',结果为:“initWithNibName self=”,所以看起来它正在加载。
        • initWithNibName:bundle: 不加载 NIB。第一次调用 -view 会加载 NIB(因此检查 self 并不能证明任何事情)。检查 self.naviagationController 不为零。如果是这样,那么您将永远不会真正加载 NIB。此外,您可能会在对 self.myViewController 的分配中泄漏(假设它是一个“保留”属性,它应该是)。你需要自动释放它。不过,感谢在那里使用访问器。在 Cocoa 中,当“什么都没有发生”时,某事是零。最常见的情况是您没有在 IB 中连接它。
        • 啊,谢谢 Rob,在那里没有看到您的评论 - 问题实际上是 self.navigationController 为零。不知道为什么(见下面我的回答)。
        【解决方案10】:

        除了这里的其他答案,

        当您从情节提要中实例化 ViewController 时使用的标识符不正确时,通常会发生这种情况。例如

        [[self getStoryboard] instantiateViewControllerWithIdentifier:MyVC];

        如果 MyVC 是某个其他 ViewController 的标识符,则可能会发生这种情况。

        OP 在这里使用nib 而不是故事板。但答案适用。

        【讨论】:

          【解决方案11】:

          页面已显示,但在调试视图层次结构和设备(模拟器中)中不可见,问题基于和 我找到了解决方法:

          func viewWillLayoutSubviews{
               if day == true{
                      self.view.backgroundColor = .clear
               }else{
                      self.view.backgroundColor = .blue
               }
          }
          

          不要尝试在layoutsubviews的功能中实现self.view(viewcontrollers视图)。所以最好在viewwillappear或viewdidload中使用self.view。从 v-14 设备开始出现此问题。

          希望它也对你有用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-06-12
            • 1970-01-01
            • 2014-03-03
            • 1970-01-01
            • 1970-01-01
            • 2011-05-19
            • 1970-01-01
            相关资源
            最近更新 更多