在iOS中使用多个Storyboard

我的目标是创build一个选项卡式应用程序,然后每个选项卡的视图都是在单独的故事板中构build的。

故事板截图

我的主板是一个标签视图。

然后我用2个视图控制器创build一个二级故事板(故事板#2)。 第一个视图控制器(也打勾为初始)有一个button,并segue(模态)第二视图。 第一视图控制器

我设法加载视图通过子类化和重写故事板#2 loadView。 loadView覆盖

这里是模拟器输出。

模拟器

当点击“点击我”button时,我得到一个EXC_BAD_ACCESS 。 segue不起作用,好像第二个故事板没有被完全加载。

有没有人试图做到这一点,并得到它的工作? 有一个来自SkillMaster.net的YouTubevideo,但他没有演示如果一个segue正在二级故事板下工作。 video在这里:http: //youtu.be/D4_twoYvB4M

感谢您的任何意见和帮助!

截图:

  • http://www.box.com/s/njnyzjoqg8pnqofv838m
  • http://www.box.com/s/8dqygclmp5ic86e47bi5
  • http://www.box.com/s/k7foe7gpgh2rs3y8gqxd
  • http://www.box.com/s/rym111x7xqxqao51ruip

这些是我在多个故事板上看到的最好的文章。

  • 故事板最佳做法
  • 连接故事板和segues

他不仅告诉你如何用代码创build一个新的故事板

  • 在实践中推荐多个故事板(更多模块化代码)
  • 讨论何时使用xibs与故事板(xibs保存视图,storboard基于控制器)
  • 提供了一个链接故事板与github上的segues的类

请注意,这最后一点是重要的,因为多个故事板的主要缺点是,你通常不能将它们连接到segues,但是robs库允许有一点欺骗

另见这里讨论

OP编辑他的问题,包括答案:

 UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"HelpStoryboard" bundle:nil]; UIViewController* initialHelpView = [storyboard instantiateInitialViewController]; initialHelpView.modalPresentationStyle = UIModalPresentationFormSheet; [self presentModalViewController:initialHelpView animated:YES]; 

当然,你调用这个的位置是有意义的,因为你可能在内存中有2个故事板和它们的视图堆栈。 所以,如果你从其他故事板的视图控制器之外调用这个代码,可能是最好的。

我已经研究了大黄提出的RBStoryboardLink方法。 这个实现取代了看起来很奇怪的视图控制器的属性。 我相信我已经find了避免这种情况的方法。 这是演示项目 。

导航控制器

导航控制器可以将一个引用的视图控制器设置为一个根。 这种视图控制器的实现可能是这样的:

 @interface ExternNavigationController : UINavigationController @property (strong, nonatomic) NSString *storyboardName; @property (strong, nonatomic) NSString *sceneIdentifier; @end @implementation ExternNavigationController - (void)awakeFromNib { NSAssert(self.storyboardName, @"storyboardName is required"); UIStoryboard *storyboard = [UIStoryboard storyboardWithName:self.storyboardName bundle:nil]; UIViewController *vc = self.sceneIdentifier ? [storyboard instantiateViewControllerWithIdentifier:self.sceneIdentifier] : [storyboard instantiateInitialViewController]; self.viewControllers = @[vc]; } @end 

视图控制器

当您想要推送在外部故事板中定义的视图控制器时,问题就开始了。 属性被复制时就是这种情况。 而不是这个,我们可以实现一个自定义的segue,它将从外部的故事板中用一个真实的目标控制器replace一个真正的目标控制器。

 @interface ExternStoryboardSegue : UIStoryboardSegue @end @implementation ExternStoryboardSegue - (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(ExternViewController *)destination { NSAssert(destination.storyboardName, @"storyboardName is required"); UIStoryboard *storyboard = [UIStoryboard storyboardWithName:destination.storyboardName bundle:nil]; UIViewController *vc = destination.sceneIdentifier ? [storyboard instantiateViewControllerWithIdentifier:destination.sceneIdentifier] : [storyboard instantiateInitialViewController]; return [super initWithIdentifier:identifier source:source destination:vc]; } - (void)perform { [[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:YES]; } @end 

ExternViewController用作占位符,包含替代属性(storyboardName和sceneIdentifier)所需的。

 @interface ExternViewController : UIViewController @property (strong, nonatomic) NSString *storyboardName; @property (strong, nonatomic) NSString *sceneIdentifier; @end @implementation ExternViewController @end 

我们需要为占位符视图控制器设置这些属性和自定义类。 并且还将视图控制器与ExternStoryboardSegue链接起来。

IB截图

从我的一个XIB文件导航到GUI的一个更复杂的部分,对于这个部分我使用了一个Storyboard。 所以我的XIB中的一个button将导航到故事板。 我有这个代码是:

 UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardIdentifier" bundle:nil]; UIViewController* myStoryBoardInitialViewController = [storyboard instantiateInitialViewController]; [self.navigationController pushViewController:myStoryBoardInitialViewController animated:YES]; 

这将成功推动我的StoryBoard到视图。 上面的代码是从一个button“Touch Up Inside”中调用的。

从Xcode 7(并移植回iOS8),现在可以有故事板引用。 在这个WWDC 2015会议中提到了它(它在第一个小时左右开始讨论它们)。 基本上所有你所要做的就是select你想移动到分离故事板的ViewController,然后点击Editor-> Refactor to Storyboard …。 给它一个名字,瞧:

在这里输入图像描述

请注意,如果你有VC被移动到新的故事板,并没有引用它(应该是),你应该从main.storyboard删除他们的引用(放松他们将保持在新创build的故事板,你是只删除对它们的引用)。

苹果的文档说,你可能有多个故事板。 不幸的是,他们没有详细说明如何做到这一点。 正如你已经发现的,Interface Builder不会帮你,所以你必须在代码中做到这一点。 它非常类似于加载XIB:

 [UIStoryboard storyboardWithName:@”MyNewStoryboard” bundle:myBundle] 

话虽如此,如果你不是像你在评论中所说的那样“想要一个大的/臃肿的故事板”,那么XIB真的是要走的路。 这个“大”就是好处:VC之间的所有转换都在一个地方。 有多个故事板是真的,以便您可以支持通过您的应用程序的多个不同的和不相关的stream程:例如,一个复杂的configurationstream程故事板和另一个为主要用户stream程。

我发现,如果在第二个故事板中有一个命名的segue,您希望在调用中执行SegueWithIdenitfier:您必须在源ViewController的“Identity”选项卡中设置“Storyboard ID”字段。

例如,如果你给一个名为“ViewController1”的VC和一个名为“segue1”的segue给另一个VC,那么将“ViewController1”的“Storyboard ID”设置为任何内容(比如说“viewC1”),然后在ViewController1.m中,使用[self performSegueWithIdentifier:@“segue1”sender:self]。

Xcode 8.2.1

您可以在外部故事板中引用视图控制器。

从TabBarController到Storyboard Reference的关系

将连接从UITabBarController拖动到外部Storyboard参考,将其添加为“视图控制器”关系。 在主要故事板中显示为“Item / square”,但在外部故事板中,您应该添加一个UITabBarItem并为该选项卡定义名称和图像。

在这里输入图像描述

属性检查器,当Storyboard Reference被选中。

您还需要在其故事板 (此处未显示)中 向外部控制器提供“故事板ID” ,并在引用中引用它的名称。