15

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

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

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

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

4

1 回答 1

20

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

当您选择 B 时,实际上您是在选择 B/C 组合,因为 NavController 的堆栈中始终至少有一个 viewController(即 theirtopViewController和 their [viewControllers objectAtIndex:0])。

所以你确实有直接从 A 到 C 的关系。

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

无论哪种情况,要将数据传递给 C,您都需要在其头文件中声明一个属性

    @interface CviewController: UIViewContrller
    @property (assign) int dataFromA;
    @end

推动转场

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

在 AviewController 的 prepareForSegue 中:

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

在情节提要中,可以在两个共享公共 UINavigationController 的viewController 之间创建一个 push segue line 。但是,当您运行此程序时,您将收到崩溃错误:

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

每个好的 push 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];
}

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

于 2013-01-13T20:10:46.903 回答