我有问题,
以下是我的StoryBoard,
第一个控制器是TabBarController
,
它与A(ViewController)的关系。
A是ViewController
,
B是NavigationController
,通过modal
字段向B更改页面
C是ViewController
,C将由push
更改为另一个页面,因此我需要一个NavigationController
好的,我想将值从A传递给C,
现在我可以通过prepareForSegue
,将值从A传递给B.
但是,因为B和C有关系而不是segue,
所以我不能通过prepareForSegue
来传递从B到C的值!
如何使用StoryBoard在NavigationController和ViewController之间传递值?
答案 0 :(得分:20)
故事板图片在这里有点误导。
当你转向B时,实际你正在转向B / C组合,因为NavControllers总是在它们的堆栈中至少有一个viewController(它们是topViewController
和它们的{{ 1}})。
所以你确实有从A到C的直接关系。
如何访问该控制器取决于您的segue是模态还是 push 。在你的情况下它是模态的,但我会描述两者,所以你可以看到差异。
在任何一种情况下,要将数据传递给C,您需要在其头文件中声明一个属性
[viewControllers objectAtIndex:0]
推送segue
在push segue中,它实际上是C,它是destinationViewController,而不是B.实际上push segue由B管理,它是A和C的UINavigationController。推送segue背后的代码是形式
@interface CviewController: UIViewContrller
@property (assign) int dataFromA;
@end
在AviewController的prepareForSegue中:
[self.navigationController pushViewController:otherViewController];
故事板中的可能可以在两个viewController之间建立一个推送segue线,它们不共享一个共同的UINavigationController。但是,当您运行此操作时,您将收到崩溃错误:
'找不到segue'pushC'的导航控制器。 Push segues只能在源控制器由UINavigationController实例管理时使用。
每一个推动segue的背后都有一个导航控制器。
模态segue
隐藏在模态Segue背后的代码是UIViewController方法
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CviewController* controller = segue.destinationViewController;
[controller setDataFromA:self.data];
}
在NavController / ViewController组合的模态segue中,目标viewController是segue线指向的任何内容。如果它指向一个viewController,那就是segue.destinationController(并且将忽略UINavigationController,这不是你想要的);如果它指向UINavigationController,就像在这种情况下, 将是它的destinationController。但是访问viewController仍然很简单,因为它将是导航控制器的topViewController。
在AviewController的prepareForSegue中:
- (void)presentViewController:(UIViewController *)viewControllerToPresent
请注意,在这种情况下,我们必须使用旧式[[消息传递]语法]。如果我们使用modern.property.syntax,我们会收到编译错误。那是因为程序不知道desinationViewController的类型,并且拒绝接受topViewController作为未知类型的属性。但它 很高兴[发送[真实消息]]到未知类型。我们还必须(类型转换*)来避免编译器警告。