Ios 如何使用故事板在NavigationController和ViewController之间传递值?

Ios 如何使用故事板在NavigationController和ViewController之间传递值?,ios,uiviewcontroller,uinavigationcontroller,Ios,Uiviewcontroller,Uinavigationcontroller,我有个问题, 以下是我的故事板, 第一个控制器是一个TabBarController, 它与(视图控制器)的关系。 A是一个视图控制器, B是一个NavigationController,通过modalsegue将页面更改为B C是一个ViewController,C将通过push切换到另一个页面,因此我需要一个导航控制器 好的,我想把值从A传递到C, 现在我可以通过prepareforsgue,将值从A传递到B 但是,因为B和C有关系但没有顺序, 所以我不能通过prepareforsgu

我有个问题,
以下是我的故事板,
第一个控制器是一个
TabBarController

它与(视图控制器)的关系。


A是一个
视图控制器

B是一个
NavigationController
,通过
modal
segue将页面更改为B
C是一个
ViewController
,C将通过
push
切换到另一个页面,因此我需要一个导航控制器

好的,我想把值从A传递到C,
现在我可以通过
prepareforsgue

将值从A传递到B 但是,因为B和C有关系但没有顺序,
所以我不能通过
prepareforsgue
将值从B传递到C


如何使用序列图像板在NavigationController和ViewController之间传递值?

序列图像板图像在这里有点误导

当您切换到B时,实际上是切换到B/C组合,因为导航控制器的堆栈中始终至少有一个viewController(即它们的
topViewController
[viewController objectAtIndex:0]

所以你有一个直接从a到C的关系

您访问该控制器的方式取决于您的segue是modal还是push。在您的情况下,它是模态的,但我将描述两者,以便您可以看到差异

在任何一种情况下,要将数据传递给C,都需要在它的头文件中声明一个属性

    @interface CviewController: UIViewContrller
    @property (assign) int dataFromA;
    @end
推送序列

在推送序列中,实际上是C是destinationViewController,而不是B。事实上,推送序列由B控制,B是a和C的UINavigationController。推送序列后面的代码的形式为
[self.navigationController pushViewController:otherViewController]

在AviewController的准备过程中:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
        {
         CviewController* controller = segue.destinationViewController;
        [controller setDataFromA:self.data];
    }
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
     CviewController* controller = 
        (CviewController*)[[segue destinationViewController] topViewController];
    [controller setDataFromA:self.data];
}
在情节提要中,可以在两个不共享公共UINavigationController的ViewController之间创建推送序列线。但是,当您运行此命令时,将出现崩溃错误:

'找不到segue'pushC'的导航控制器。仅当源控制器由UINavigationController实例管理时,才能使用推送序列。'

每一个好的推送序列后面都有一个导航控制器

模态序列

隐藏在模态序列后面的代码是UIViewController方法
-(无效)presentViewController:(UIViewController*)viewControllerToPresent

在导航控制器/视图控制器组合的模式序列中,目标视图控制器是序列线指向的任何对象。如果它指向一个viewController,那就是segue.destinationController(将忽略UINavigationController,这不是您想要的);如果它指向一个UINavigationController,如本例中所示,那么它就是destinationController。但访问viewController仍然很简单,因为它将是导航控制器的topViewController

在AviewController的准备过程中:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
        {
         CviewController* controller = segue.destinationViewController;
        [controller setDataFromA:self.data];
    }
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
     CviewController* controller = 
        (CviewController*)[[segue destinationViewController] topViewController];
    [controller setDataFromA:self.data];
}

注意,在这种情况下,我们必须使用老式的[[消息传递]语法]。如果我们使用modern.property.syntax,就会出现编译错误。这是因为程序不知道desinationViewController的类型,并且拒绝接受topViewController作为未知类型的属性。但它很乐意[发送[真实消息]]给未知类型。我们还必须(typecast*)以避免编译器警告

您好,谢谢您的回答,我已经尝试了您的解决方案,但现在控制台显示以下错误“[UINavigationController setDataFromA:]:发送到实例0x7430850的选择器无法识别”。“怎么了?”“您没有将消息发送到UINavigationController,而是将其发送到UIViewController(C)您的故事板序列从A运行到B。删除它,并将其替换为从A运行到C的序列。如果我将序列从A添加到C,B在哪里?”?我需要一个NavigationController,因为C将推送到另一个ViewControllerC包含在B中。在故事板中,您可以通过选择C,菜单>编辑器>嵌入>导航控制器来“调用”B