【问题标题】:iOS Storyboard - Navigation Controller Not WorkingiOS Storyboard - 导航控制器不工作
【发布时间】:2013-07-29 18:12:56
【问题描述】:

我在使用 Storyboard 的 iOS 项目中遇到导航控制器问题。

项目的主要部分是一个UITabBar。当应用程序第一次加载屏幕 RegisterViewController 时:

当用户点击“注册”按钮时,会发出 HTTP POST 请求,然后在收到响应(JSON 对象)后,屏幕 QuestionnaireViewController 会使用:

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

QuestionnaireViewController *questionnaireViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"QuestionnaireView"];
[questionnaireViewController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[questionnaireViewController setQuestionsAndAnswers:_questionsAndAnswers];

[self presentViewController:questionnaireViewController animated:NO completion:nil];

当用户点击 QuestionnaireViewController 中的单元格时,会向 prepareForSegue:sender: 发送一条消息:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UINavigationController *navigationController = segue.destinationViewController;

    AnswersViewController *answersViewController = [[navigationController viewControllers] objectAtIndex:0];

    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    NSArray *answers = [[_questionsAndAnswers objectAtIndex:indexPath.row] objectForKey:@"answers"];

    [answersViewController setAnswers:answers];
}

此时应用程序崩溃并出现以下错误: -[AnswersViewController viewControllers]:无法识别的选择器发送到实例。

下面是我的故事板更全面的概述,它可能有助于理解我哪里出错了:

我不知道如何解决这个问题,希望有人能够提供帮助。

谢谢, 尼克

【问题讨论】:

  • 你不应该展示问卷视图控制器,你应该展示它嵌入的导航控制器。然后在 prepareForSegue 中,你不需要对导航控制器做任何事情,AnswersViewController 是目标视图控制器。
  • rdelmar:我现在觉得有点傻——我要如何呈现问卷视图控制器嵌入的导航控制器?
  • 就像任何其他控制器一样,给它一个标识符并使​​用instantiateViewControllerWithIdentifier:,然后是presentViewControllerAnimated:completion。
  • rdelmar:我试过了,但是现在 QuestionnaireViewController 中的表格视图是空的。

标签: ios uiviewcontroller uinavigationcontroller storyboard uitableview


【解决方案1】:

首先,您应该展示导航控制器,而不是它的根视图控制器。然后当你想用一些数据填充根视图控制器时,你需要将它作为导航控制器的根视图控制器来引用:

UINavigationcontroller *questionnaireNavController = [self.storyboard instantiateViewControllerWithIdentifier:@"QuestionnaireNavigationController"];
[questionnaireNavController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
QuestionnaireViewController *qvc = (QuestionnaireViewController *)[questionnaireNavController topViewController];
[qvc setQuestionsAndAnswers:_questionsAndAnswers];

[self presentViewController:questionnaireNavController animated:NO completion:nil];

其次,在 prepareForSegue:sender 中:你根本不需要引用导航控制器:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    AnswersViewController *answersVC = segue.destinationViewController;
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    NSArray *answers = [[_questionsAndAnswers objectAtIndex:indexPath.row] objectForKey:@"answers"];

    [answersVC setAnswers:answers];
}

【讨论】:

  • 非常感谢 rdelmar。我几乎第一次在那里,但是使用 alloc/init 将数据发送到 QuestionnaireViewController。您的答案几乎 100% 正确 - 我必须使用以下方法获取指向 qvc 的指针: (QuestionnaireViewController *)[[questionnaireNavController viewControllers] objectAtIndex:0] 与您得到的解决方案一样:“'UINavigationController' 没有可见的@interface 声明选择器'rootViewController'”。再次,非常感谢 - 我可以停止拔掉我剩下的头发了。
  • @Nick,哦,对,对不起。它应该是 [questionnaireNavController topViewController] (但你的方式也可以)。我已经在我的帖子中更正了。
  • 不用道歉,你帮了大忙。在这两种方式中,您会说其中一种方式比另一种方式更“正确”吗?
  • @Nick,只有一个视图控制器,这两种方法是等效的,但是无论有多少控制器,viewControllers[0] 都将始终是根视图控制器,而我这样做的方式给出了你是堆栈顶部的视图控制器,这将是屏幕上的那个。
  • 听起来你的方法是带和大括号的方式,因此会改变我的实现。
【解决方案2】:

您没有正确获取 navigationController。代替segue.destinationViewController,使用self.navigationController

通过调用 segue.destinationViewController,您将获得指向您正在转至的 VC (AnswersViewController) 的指针,它不理解消息 viewControllers,因为它不是 UINavigationController。

AnswersViewController 也是 objectAtIndex:1 我相信,请检查一下。

【讨论】:

  • 这在大多数情况下是正确的,但似乎他甚至没有分配 AnswersViewController,因此它不会存储在 navigationController 的 viewControllers 数组中,如果它是情节提要中的视图控制器,那么他应该使用 [storyBoard instantiateWithIdentifyer:@""];如果它是选项卡视图控制器的选项卡,那么他应该做 [tabControlelr viewControllerAtIndex:];那不是写函数,但会有类似的东西
  • 迪伦,非常感谢您的快速回复。如果我将其更改为 self.navigationController 我会收到以下错误:“只有在源控制器由 UINavigationController 的实例管理时才能使用推送序列。”
  • 根据您的屏幕截图(下方),QuestionViewController 和 AnswerViewController 都嵌入在 UINavigationController 中。确认是这样。如果 QuestionViewController 不在导航堆栈中,请将其嵌入其中。 (@A'saDickens 如果 AnswersViewController 在故事板的导航堆栈中,它应该从 nib 实例化)
  • Dylan,QuestionnaireViewController 嵌入在 UINavigationController 中,QuestionViewController 与 QuestionnaireViewController 有一个推送序列。我还添加了一张新图片,更全面地概述了我的故事板。
  • 我的建议是使用调试器单步执行 prepareForSegue 并确认 self.navigationController 不为 nil,确认 self 是 QuestionnaireViewController,并检查一切是否正常,如果没有的话不行,发到github上,我去看看。
猜你喜欢
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多