【问题标题】:How to pass data to view controller being instantiated from UIStoryboard?如何将数据传递给从 UIStoryboard 实例化的视图控制器?
【发布时间】:2013-11-20 11:46:13
【问题描述】:

我使用以下代码实例化并推送我的UIViewController

RIYNetworkGameViewController *ngvc = 
      [[UIStoryboard storyboardWithName:@"Main" bundle:nil] 
       instantiateViewControllerWithIdentifier:@"networkGame"];
ngvc.food = 42;
[self.navigationController pushViewController:ngvc animated:YES];

除了实例化后将值 42 分配给属性,有没有办法传入该值以便在实例化期间可以使用它?我只使用storyboards,并没有任何nib 文件,所以我不确定调用了哪些方法来实例化UIViewController

编辑:我在viewWillLayoutSubviews 中创建并呈现了一个 SKScene,因此我需要在调用 viewWillLayoutSubviews 之前获取数据。

【问题讨论】:

  • 为什么在使用 Storyboard 的时候要手动推动控制器?
  • 这个特定的视图控制器是为了响应正在创建的游戏中心比赛而创建的,所以我必须在运行时创建控制器。在 Game Center 创建比赛后,会调用一个委托方法来创建视图控制器。我不确定有没有办法用故事板做到这一点,有吗?
  • 那你为什么不用 UIStoryboardSegue 的呢?
  • 您可以使用 userdefault 或一些全局引用实例变量。但它不是标准代码。
  • 我想避免使用全局引用变量或用户默认值。 @Akki - 我是使用 Storyboards / IB 的新手。 UIStoryboardSegue 比我现在做的更好吗?

标签: ios objective-c uiviewcontroller uistoryboard


【解决方案1】:

您可以在- prepareForSegue:sender:中传递您的数据

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSString *identifier = [segue identifier];
    if ([identifier isEqualToString:@"yourSegueName"]) {
        YourControllerClass *controller = [segue destinationViewController];
        [controller setPassingData:passingData]
    }
}

要使用此功能,请致电 [self performSegueWithIdentifier:@"yourSegueName" sender:sender] 而不是 [self.navigationController pushViewController:controller animated:YES]

【讨论】:

  • prepareForSegue 方法不带任何参数 - 我如何将我的对象传递给它?我试图避免使用某种全局变量。这不就像我正在做的那样,除了你可以看到它的故事板吗? (我问是因为我是新人。请不要介意。)这比我现在做的更好吗?
  • 我试过这个 - 也许我误解了,因为它对我不起作用。如果我这样做` RIYNetworkGameViewController * controller = [segue destinationViewController]; controller.food = 43;`当segue完成时,food = 0;在我之前的代码中,分配是持久的。
  • @John,这很奇怪,因为它对我来说总是很好。您可以通过发件人将所需参数传递给-prepareForSegue:。这是我当前项目的工作示例:NSString *identifier = [segue identifier]; if ([identifier isEqualToString:@"photoControllerSegue"]) { SUGalleryViewController *gallery = [segue destinationViewController]; [gallery setPhotoSource:self.user]; UIGestureRecognizer *gr = (UIGestureRecognizer*)sender; [gallery setStartingIndex:(gr.view ? gr.view.tag - 1 : 0)]; }`
  • 它对我不起作用。而不是使用“。”我也尝试使用setFood:42,但在控制器加载后,食物的值为 0。
  • 它有效 - 这是我的错!我在标识符中打错了字。但我不明白这如何解决我的问题。 (在实例化控制器之前,我仍然无法将对象传递给 init 等)。我还是得让控制器实例化,然后设置一个属性。
【解决方案2】:

此时,您的视图控制器已实例化但未加载!

您应该只提供初始化所需的信息。 例如,如果“food”是一个初始化相关数据,你应该创建一个新的指定初始化器,如instantiateViewControllerWithIdentifier:@"networkGame" andFood:42
(在这种情况下,在它的实现中调用[super init])。

如果您的数据传递问题与初始化无关,您为什么要使用 ngvc.food = 42; 以外的其他方式来传递数据?这是很好的做法。

【讨论】:

  • 我想传递可用于实例化它的数据 - 如果我可以将数据传递给正在初始化的视图控制器,那可能会更好。
  • 所以你应该创建一个新的指定初始化器,比如instantiateViewControllerWithIdentifier:@"networkGame" andFood:42 不要忘记在它的实现中调用[super init]。这能回答你的问题吗?
  • 我不这么认为——修改 UIStoryboard 可以让我将数据传递给 UIStoryboard,但我不知道 UIStoryboard 将如何将该数据传递给我的视图控制器上正在调用的任何 init 方法。
  • 故事板是你的 MVC 的视图,视图不拥有自己的数据,它应该由视图控制器管理。所以我不确定你想在这里做什么。在另一条评论中,您说您在游戏中心相关委托中实例化视图,您可以使用 preformSegueWithIdentifier:@"identifierSetInTheStoryboardInspector" 方法,然后实现此方法来配置您的目标视图控制器(此方法将用于离开视图中的任何 segue,所以在里面你应该检查标识符)你能提供更多关于你在做什么和你的限制的具体细节吗?
  • 然后您可以在目标视图控制器中实现 viewDidLoad 以使用先前在 prepareForSegue: 方法 (ngvc.food = 42;) 中设置的食物值做任何您想做的事情,该方法在您调用 preformSegueWithIdentifier 时执行(尽管我在之前的评论中说过,你不应该实施,我的意思是 prepareForSegue: 抱歉)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-28
  • 1970-01-01
  • 2018-10-29
相关资源
最近更新 更多