将信息从 UINavigationController 传递到嵌入式 UIViewController
Posted
技术标签:
【中文标题】将信息从 UINavigationController 传递到嵌入式 UIViewController【英文标题】:Passing info from UINavigationController to embedded UIViewController 【发布时间】:2014-01-29 20:51:40 【问题描述】:概要
由于我没有让我的应用按我的意图传递数据,我被引导提出以下问题:
一般来说,如何将数据从导航控制器传递到其 嵌入式视图控制器? 具体来说,prepareForSegue
导航控制器中的方法曾经被调用过吗?如果有,怎么做?
设置
我有以下几点:
一个视图,标题为用户视图控制器,链接到自定义类JRMUserViewController
(扩展UIViewController
)。此视图嵌入:
导航视图,标题为导航到用户视图,链接到自定义类JRMNavigationToUserViewController
(扩展UINavigationController
)。重要提示:首先,我没有在导航控制器中嵌入用户视图控制器。导航控制器及其链接类不存在。
A Table View 标题为Issue Table View Controller,链接到自定义类JRMIssuesTableViewController
(扩展UITableViewController
)。
一个按钮链接到模态转场,该转场转至导航到用户视图。转场由文本“@987654332”标识@"。
预期功能
这个想法是,当我在问题表视图控制器上时,我可以点击按钮,它会带我到用户视图控制器,在那里我将看到当前用户的头像,以及带有当前用户全名的标签。
为了实现这一点(在我将 User View Controller 嵌入导航控制器之前),我在前者的 prepareForSegue 方法中将数据从 JRMIssuesTableViewController
传递到 JRMUserViewController
:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
NSLog(@"\nSEGUE IDENTIFIER:\n%@", [segue identifier]);
if([[segue identifier] isEqualToString:@"IssuesToUserView"])
JRMUserViewController *vc = [segue destinationViewController];
vc.currentUser = self.currentUser;
NSURL *url = [[NSURL alloc] initWithString:[vc.currentUser.avatarUrls objectForKey:@"48x48"]];
NSLog(@"\nURL:\n%@", url);
NSData *data = [NSData dataWithContentsOfURL:url];
[vc.view addSubview:vc.avatar];
[vc.avatar setImage:[[UIImage alloc] initWithData:data]];
vc.userLabel.text = vc.currentUser.displayName;
它成功了。单击第一个视图上的按钮将我带到第二个视图,其中显示了当前用户的信息:
意外行为
此后,出于必要,我不得不将用户视图控制器嵌入到我之前提到的导航控制器中。当然,在这样做之后,我在运行时遇到了未捕获的异常,因为在我重写的 prepareForSegue 中,我将消息发送到导航控制器而不是用户视图控制器。为了解决这个问题,我扩展了UINavigationController
,将其命名为JRMNavigationToUserViewController
,并将导航视图链接到它,正如我在设置中提到的那样。
然后,考虑到 UINavigationController
在进入其嵌入式视图之前会调用自己的 prepareForSegue
,我覆盖了 JRMNavigationToUserViewController
中的 prepareForSegue
方法:
- (id)passValuesToDesitinationOfSegue:(UIStoryboardSegue *)segue
NSLog(@"Calling [JRMNavigationToUserViewController passValuesToDestinationOfSegue]");
JRMUserViewController *destination = [segue destinationViewController];
destination.server = self.server;
destination.currentUser = self.currentUser;
destination.avatar = self.avatar;
[destination.view addSubview:destination.avatar];
destination.userLabel = self.userLabel;
return destination;
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
NSLog(@"Calling [JRMNavigationToUserViewController prepareForSegue]");
[self passValuesToDesitinationOfSegue:segue];
这一次,当我点击按钮时,用户视图控制器没有收到数据。它看起来像这样:
显然,JRMNavigationToUserViewController
中的 prepareForSegue
方法从未被调用,因为它会记录消息:
Calling [JRMNavigationToUserViewController prepareForSegue]
Calling [JRMNavigationToUserViewController passValuesToDestinationOfSegue]
我在控制台的任何地方都找不到这些行。
总结
这是我的问题:
一般来说,如何将数据从导航控制器传递到其 嵌入式视图控制器? 具体来说,prepareForSegue
导航控制器中的方法曾经被调用过吗?如果有,怎么做?
【问题讨论】:
导航控制器通常没有自己的内容——它们希望管理其他视图控制器的堆栈,并显示当前位于堆栈顶部的控制器视图。如果您将UINavigationController
子类化为显示自己的内容,那么您肯定会让自己的生活变得比需要的更加困难。你能说明你决定继承UINavigationController
的原因吗?
我对它进行了子类化,因此我可以覆盖 prepareForSegue
以尝试将数据传递到嵌入视图。然而,我怀疑这表明我对 UINavigationController 的工作原理有多少误解。这就是我问这个问题的原因。
【参考方案1】:
你在这里误用了UINavigationController
。看看你的故事板:你有一个表格控制器,它以某种方式呈现一个导航控制器,而导航控制器又具有一个用户控制器作为它的根控制器。我认为您想要的是让导航控制器包含表格控制器,并在表格上点击触发对用户视图控制器的推送。因此,导航控制器应该在左侧,表格控制器在中间,用户控制器在右侧。
然后,表格控制器中的-prepareForSegue:sender:
方法将被写入,使其查看选定的单元格并设置用户控制器的相应属性(这是segue 的目的地)。
【讨论】:
你是对的。我摆脱了导航控制器,它工作了(问题视图上游已经有一个导航控制器)。您的回答帮助我更好地理解UINavigationController
。谢谢!以上是关于将信息从 UINavigationController 传递到嵌入式 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章
从模态视图或推送视图调用父方法到presentingViewController