如何使用 StoryBoard 在 NavigationController 和 ViewController 之间传递值?
Posted
技术标签:
【中文标题】如何使用 StoryBoard 在 NavigationController 和 ViewController 之间传递值?【英文标题】:How can I pass value between NavigationController and ViewController with StoryBoard? 【发布时间】:2013-01-13 19:34:38 【问题描述】:我有问题,
以下是我的故事板,
第一个控制器是TabBarController
,
它与 A (ViewController) 的关系。
A 是ViewController
,
B 是 NavigationController
,A 将页面更改为 B 由 modal
segue
C 是 ViewController
,C 将通过 push
更改为另一个页面,所以我需要 NavigationController
好的,我想将值从 A 传递到 C,
现在我可以通过 prepareForSegue
将值从 A 传递到 B,
但是,由于B和C有关系但没有segue,
所以我不能通过 prepareForSegue
将值从 B 传递给 C!!!
【问题讨论】:
【参考方案1】:故事板图像在这里有点误导。
当您选择 B 时,实际上您正在选择 B/C 组合,因为 NavController 的堆栈中始终至少有一个 viewController(这是他们的 topViewController
和他们的 [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 之间建立一条推线。但是,当你运行它时,你会得到一个崩溃错误:
'找不到用于 segue 'pushC' 的导航控制器。只有当源控制器由 UINavigationController 的实例管理时,才能使用推送 segue。'
每一个好的推送转场背后都有一个导航控制器。
模态转场
隐藏在模态 Segue 后面的代码是 UIViewController 方法- (void)presentViewController:(UIViewController *)viewControllerToPresent
在 NavController/ViewController 组合的模态 segue 中,目标 viewController 是 segue 线指向的任何内容。如果它指向一个 viewController,那就是 segue.destinationController (并且 UINavigationController 将被忽略,这不是你想要的);如果它指向 UINavigationController,在这种情况下,that 将是它的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*) 以避免编译器警告。
【讨论】:
您好,谢谢您的回答,我已经尝试过您的解决方案,但现在控制台显示以下错误“[UINavigationController setDataFromA:]: unrecognized selector sent to instance 0x7430850”。 @@怎么了? 你没有把消息发给 UINavigationController,你把它发给你 UIViewController (C) 您的故事板 Segue 正在从 A 运行到 B。删除它,并将其替换为从 A 到 C 运行的 segue。 如果我从 A 到 C 添加一个 segue,B 在哪里?我需要一个 NavigationController 因为 C 会推送到另一个 ViewController C 包含在 B 中。在情节提要中,您可以通过选择 C、菜单 > 编辑器 > 嵌入 > 导航控制器来“调用”B以上是关于如何使用 StoryBoard 在 NavigationController 和 ViewController 之间传递值?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 uiviewcontroller/storyboard 上的 uibutton 在 uipageviewcontroller 中推进页面
如何使用非基础本地化在 Xcode 中预览 Storyboard
如何使用 StoryBoard 在 UITableViewCell 内快速构建一个 collectionView