如何使用StoryBoard在NavigationController和ViewController之间传递值?

Azu*_*hen 15 uiviewcontroller uinavigationcontroller ios

我有一个问题,
以下是我的StoryBoard,
第一个Controller是一个TabBarController,
它与A(ViewController)的关系.

如何使用StoryBoard在NavigationController和ViewController之间传递值?
A是a ViewController,
B是a NavigationController,A改变页面到B由modalsegue
C是a ViewController,C将改为另一个页面push所以我需要一个NavigationController

OK,我想将值从A传递给C,
现在我可以从A传递值到B by prepareForSegue,
但是,因为B和C有关系而不是segue,
所以我不能通过prepareForSegue!!! 将值从B传递给C !

如何使用StoryBoard在NavigationController和ViewController之间传递值?

fou*_*dry 20

故事板图像在这里有点误导.

当你转向B时,实际上你正在转向B/C组合,因为NavControllers总是在它们的堆栈中至少有一个viewController(这是他们topViewController和他们的[viewControllers objectAtIndex:0]).

所以你确实有一个直接从A到C的关系.

如何访问该控制器取决于您的segue是模态还是推送.在你的情况下它是模态的,但我会描述两者,所以你可以看到差异.

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

    @interface CviewController: UIViewContrller
    @property (assign) int dataFromA;
    @end
Run Code Online (Sandbox Code Playgroud)

推塞

在push segue中,它实际上是C,它是destinationViewController,而不是B.实际上push segue由B管理,B是A和C的UINavigationController.推送segue背后的代码是形式
[self.navigationController pushViewController:otherViewController];

在AviewController的prepareForSegue中:

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

这是可能的故事板进行两次viewControllers之间的推线赛格瑞那些共享一个共同的UINavigationController.但是,当您运行此操作时,您将收到崩溃错误:

'无法为segue'pushC'找到导航控制器.Push segues只能在源控制器由UINavigationController实例管理时使用.

每个好推送segue背后都有一个导航控制器.

模态segue

隐藏在模态Segue背后的代码是UIViewController方法
- (void)presentViewController:(UIViewController *)viewControllerToPresent

在NavController/ViewController组合的模态segue中,目标viewController是segue线指向的任何内容.如果它指向一个viewController,那就是segue.destinationController(并且将忽略UINavigationController,这不是你想要的); 如果它指向一个UINavigationController,因为在这种情况下,将是它的destinationController.但是访问viewController仍然很简单,因为它将是导航控制器的topViewController.

在AviewController的prepareForSegue中:

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

请注意,在这种情况下,我们必须使用旧式[[消息传递]语法].如果我们使用modern.property.syntax,我们会收到编译错误.那是因为程序不知道desinationViewController的类型,并且拒绝接受topViewController作为未知类型的属性.但它乐于[发送[实消息]一个未知的类型.我们还必须(类型转换*)来避免编译器警告.