【问题标题】:How to share one storyboard scene between multiple UIViewControllers如何在多个 UIViewController 之间共享一个故事板场景
【发布时间】:2012-08-29 10:22:17
【问题描述】:

在得知我最初偏离轨道但我没有更接近解决问题后,我完全重新制定了这个问题。参考这张图...

我想在代码中创建或操作 segue(以黄色突出显示),以便主视图是 MFMasterViewController 的多个子类中的任何一个(以红色突出显示)。

使用 Nibs 执行此操作时,我可以创建一个 Nib,SharedNib.xib 并将类设置为 MFMasterViewController,然后创建我的子类,例如 MFMasterViewControllerSubclassAMFMasterViewControllerSubclassB 等,然后实例化我想要使用的任何子类。 ..

MFMasterViewControllerSubclassA *controller = [[MFMasterViewControllerSubclassA alloc] initWithNibName:@"SharedNib" bundle:nil];

或者...

MFMasterViewControllerSubclassB *controller = [[MFMasterViewControllerSubclassB alloc] initWithNibName:@"SharedNib" bundle:nil];

等等

关于如何使用情节提要解决此问题的任何线索?

在我的情况下,想要这样做的原因是我所有的子类都是相同的 tableview 和数据,但排序不同,并且在写入 cels 的详细文本方面存在一些差异。我怀疑这是一种并不少见的模式。

干杯和TIA, 佩德罗:)

【问题讨论】:

  • 我知道我可以通过在我的情节提要中为每个子类制作一个场景副本来做到这一点,但是当场景完全相同并且所有版本都延续到时,这似乎是一种非常浪费的方式下一个场景相同。
  • 故事板中的控制器也是分配给类'MyViewController`的,并且MyViewControllerSubclassMyViewController的子类
  • 两个问题都是:)
  • 我不明白您为什么要尝试将 controller 分配给另一个名为 newViewControllerUIViewController?我会一起去掉UIViewController 并将第一行更改为:MyViewControllerSubclass *controller = (MyViewControllerSubclass *)[[self storyboard] instantiateViewControllerWithIdentifier:@"SharedScene"]; 另外,请确保您的子类在init 函数中调用[super init]
  • 这是一个简写。在实践中,以及我在使用 XIB 时所做的事情,它更像是UIViewController *newViewController = [self methodThatInstantiatesSubclass];,根据不同的条件,MyViewControllerSubclassAMyViewControllerSubclassB 等由方法分配。

标签: ios uiviewcontroller segue uistoryboard uistoryboardsegue


【解决方案1】:

这不是一个直接的答案,但根据您对原因的解释,这就是我将如何完成您想要的。

基本上,您需要将UITableViewDataSource(也可能是委托)与MFMasterViewController 分开,这样当segue 执行时,您可以在视图控制器中设置正确的数据源和委托。

所以在导航控制器中你需要实现prepareForSegue:sender: 方法。这是您可以在执行之前自定义 segue 的地方:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // you can set the segue identifier using Interface Builder 
    // also it is a good thing to make sure which segue you're using
    if (([segue identifier] isEqualToString:@"TheId"]) {
       id<UITableViewDataSource> dataSource = [[TableViewDataSourceImplementationA alloc] init];
       [[[segue destinationViewController] tableView] setDataSource:dataSource];
    }
}

这样你就可以得到你想要的自定义,而不需要创建你的视图控制器的子类。

如果您可以访问 WWDC 视频,请查看会话 #407 在您的应用中采用故事板。

【讨论】:

    【解决方案2】:

    对于遇到此问题的任何人,您还应该考虑更普遍地使用“策略”模式作为子类化控制器的替代方法。公认的答案是其中的一种形式,其中实施的策略来自任何数据源/委托,并且可以在运行时切换。另一个例子是https://stackoverflow.com/a/17381927/954643

    【讨论】:

      【解决方案3】:

      如果您的 .m 文件没有与任何故事板相关联,那么 self.storyboard 不会是 Nil 吗?

        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:
                                         @"MainStoryboard" bundle:[NSBundle mainBundle]];
          ViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HauptMenu"];
      

      确保将 storyboardWithName: 更改为故事板的名称。

      NSString * storyBoardName;
      if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
          storyBoardName = @"MainStoryboard_iPad";
      } else {
          storyBoardName = @"MainStoryboard_iPhone";
      }
      UIStoryboard *storyboard = [UIStoryboard storyboardWithName:
                                         storyBoardName bundle:[NSBundle mainBundle]];
      ViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"HauptMenu"];
      

      【讨论】:

      • 我在示例中称为 MyViewController 的类确实属于我的故事板中的场景和我的问题工作中的前 2 个代码示例。 MyViewControllerSubclass 是 MyViewController 的子类,但调用它的代码会失败。
      • - (id)initWithIdentifier:(NSString )identifier source:(UIViewController *)source destination:(UIViewController *)destination{ UIStoryboard *storyBoard= [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:零]; UIViewController *viewController = [storyBoard instantiateViewControllerWithIdentifier:@"testIdentifier"]; // MyViewController viewController= [[MyViewController alloc]initWithNibName:@"MyViewController" bundle:nil]; return [super initWithIdentifier:identifier source:source destination:viewController]; }
      【解决方案4】:

      我相信我终于找到了答案。我们想使用带有另一个类名的故事板 ViewController。有很多解决方法,比如使用委托,但我认为这是最好的一种。我已经在另一个话题中回答了。希望能帮助到你! https://stackoverflow.com/a/32103618/1943053

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-30
        • 1970-01-01
        • 2012-11-16
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多