故事板图像在这里有点误导。
当您选择 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*) 以避免编译器警告。