将信息从UINavigationController传递到嵌入式UIViewController

时间:2014-01-29 20:51:40

标签: ios cocoa-touch uinavigationcontroller segue uistoryboardsegue

概要

由于我没有按照我的意图让我的应用程序传递数据的方式,我将首先提出以下问题:

  • 一般情况下,如何将数据从导航控制器传递到其中 嵌入了View Controller?
  • 具体来说,是prepareForSegue 导航控制器中的方法是否被调用?如果是这样,怎么样?

设置

我有以下内容:

  • 标题为用户视图控制器的视图,已链接到自定义类JRMUserViewController(扩展为UIViewController)。
    此视图嵌入:
  • 导航视图标题为导航到用户视图,已链接到自定义类JRMNavigationToUserViewController(扩展UINavigationController)。

    重要说明:
    首先,我没有在导航控制器中嵌入用户视图控制器。导航控制器及其链接的类不存在。

  • 标题为问题表视图控制器的表视图,链接到自定义类JRMIssuesTableViewController(扩展UITableViewController)。
  • 按钮链接到模态搜索,进入 Navigaton To User View
    Segue由文字“IssuesToUserView”。

StoryBoard Setup

预期功能

我的想法是,当我在问题表视图控制器时,我可以点击按钮,它将带我进入用户视图控制器,我在那里将看到当前用户的头像,以及一个包含当前用户全名的标签。

为了实现这一点(在我将导航控制器中的用户视图控制器嵌入之前),我将数据从JRMIssuesTableViewController传递到前者的prepareForSegue方法中的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;    
   }
}

它有效。点击第一个视图上的按钮,我转到了第二个视图,其中显示了当前用户的信息:

Issue Table View

User View -- Working

意外行为

在此之后,出于必要,我不得不在我之前提到的导航控制器中嵌入用户视图控制器。当然,在执行此操作之后,我在运行时遇到了未被捕获的异常,因为在我重写的prepareForSegue中,我正在向导航控制器而不是用户视图控制器发送消息。为了解决这个问题,我扩展了UINavigationController,将其命名为JRMNavigationToUserViewController,并将导航视图链接到它,就像我在设置中提到的那样。

然后,在进入嵌入式视图之前,确定UINavigationController会调用自己的prepareForSegue,我会覆盖prepareForSegue中的JRMNavigationToUserViewController方法:

- (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];
}

这次,当我点击按钮时,用户视图控制器没有收到数据。它看起来像这样:

User View -- Not Working

显然,prepareForSegue中的JRMNavigationToUserViewController方法从未被调用过,因为它会记录消息:

Calling [JRMNavigationToUserViewController prepareForSegue]
Calling [JRMNavigationToUserViewController passValuesToDestinationOfSegue]

我无法在控制台的任何位置找到这些线条。

摘要

这也是我的问题:

  • 一般情况下,如何将数据从导航控制器传递到其中 嵌入了View Controller?
  • 具体来说,是prepareForSegue 导航控制器中的方法是否被调用?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:2)

你在这里误导了UINavigationController。看看你的故事板:你有一个表控制器,它以某种方式呈现一个导航控制器,而后者又有一个用户控制器作为其根控制器。我想你想要的是让导航控制器包含表控制器,并在表上点击触发推送到用户视图控制器的segue。因此,导航控制器应位于左侧,中间的表控制器和右侧的用户控制器。

然后,将编写表控制器中的-prepareForSegue:sender:方法,使其查看所选单元格并设置用户控制器的相应属性(即segue的目标)。