【问题标题】:Passing data between two controllers using storyboards使用情节提要在两个控制器之间传递数据
【发布时间】:2013-10-27 00:58:45
【问题描述】:

我正在尝试将数据从一个 UITableViewController 传递到另一个。这是我在初始视图控制器中的代码:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Subject *subject = (Subject *)[self.fetchedResultsController objectAtIndexPath:indexPath];
[self showList:subject animated:YES];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (void)showList:(Subject *)subject animated:(BOOL)animated {
ListsViewController *lists = [[ListsViewController alloc] initWithStyle:UITableViewStyleGrouped];
lists.subject = subject;
NSLog(@"%@", lists.subject);

[self performSegueWithIdentifier:@"showDetail" sender:self];
}

日志输出显示它有我想要的数据已被传递。但是,当我执行 segue 并在ListsViewController 中记录subject 时显示为空。

有什么想法吗?

【问题讨论】:

    标签: iphone ios objective-c storyboard segue


    【解决方案1】:

    您需要覆盖prepareForSegue:sender: 方法。快速修复将是

    - (void)showList:(Subject *)subject animated:(BOOL)animated
    {
         [self performSegueWithIdentifier:@"showDetail" sender:subject];
    }
    

    ...

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.identifier isEqualToString:@"showDetail"]) {
            ListsViewController *controller = ([segue.destinationViewController isKindOfClass:[ListsViewController class]]) ? segue.destinationViewController : nil;
            controller.subject = ([sender isKindOfClass:[Subject class]]) ? subject : nil;
        }
    }
    

    您的代码不起作用的原因是,在您的showList:animated: 方法中,您创建了一个ListsViewController 实例并为其分配了一个subject,但是这个视图控制器从未出现过。相反,performSegueWithIdentifier:sender 创建了您的 ListsViewController 类的另一个实例,它对您的 subject 一无所知。这就是为什么您需要等待 UIStoryboardSegue 从情节提要中实例化目标视图控制器,然后按照您想要的方式对其进行配置,您可以在 prepareForSegue:sender: 方法中执行此操作。

    另外,在performSegueWithIdentifier:sender 方法中使用subject 作为发件人可能不是最好的主意,因为它不是发件人:)。我要做的是在您的视图控制器类中创建一个属性主题并使用它prepareForSegue:sender:

    @interface MyViewController ()
    
    @property (strong, nonatomic) Subject *subject;
    
    @end
    
    
    @implementation MyViewController
    
    - (void)showList:(Subject *)subject animated:(BOOL)animated
    {
        self.subject = subject;
        [self performSegueWithIdentifier:@"showDetail" sender:self];
    }
    
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.identifier isEqualToString:@"showDetail"]) {
            ListsViewController *controller = ([segue.destinationViewController isKindOfClass:[ListsViewController class]]) ? segue.destinationViewController : nil;
            controller.subject = self.subject;
        }
    }
    
    ...
    @end
    

    【讨论】:

    • 值得了解 segue 的生命周期是什么样的。文档是here
    【解决方案2】:

    在此方法中实现 prepareForSegue 并传递日期

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
    if([seque.identifier isEqualToString:@"showDetail"])
    {
    ListsViewController *lists = seque.destinationViewController;
    lists.subject = subject;
    }
    }
    

    【讨论】:

      【解决方案3】:

      很好,但现在你需要添加这个:

      首先代替:

      [self performSegueWithIdentifier:@"showDetail" sender:self];
      

      您需要发送对象:

      [self performSegueWithIdentifier:@"showDetail" sender:subject];
      

      在您的 ListsViewController.h 中添加一个属性:

      @property (nonatomic, strong) Subject * subjectSegue;
      

      现在在您的第一个视图控制器中:

      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
      {
          if ([segue.identifier isEqualToString:@"showDetail"]) {
              ListsViewController * lists = (ListsViewController *)[segue destinationViewController];
              lists.subjectSegue = sender;
      }
      

      【讨论】:

        【解决方案4】:

        您需要了解performSegueWithIdentifier:sender: 创建了一个新的视图控制器实例。所以你创建的ListsViewController并没有显示在屏幕上。

        你需要重写`prepareForSegue:sender:

        - (void)showList:(Subject *)subject animated:(BOOL)animated 
        {
          [self performSegueWithIdentifier:@"showDetail" sender:self];
        }
        
        - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
        {
            if ([segue.identifier isEqualToString:@"showDetail"]) {
                ListsViewController *controller = (ListsViewController *)segue.destinationViewController;
            controller.subject = self.subject;
        }
        

        【讨论】:

          猜你喜欢
          • 2012-06-02
          • 2014-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-17
          • 1970-01-01
          • 2012-07-27
          • 1970-01-01
          相关资源
          最近更新 更多