将子视图控制器链接到故事板中的父视图控制器

您可以将子视图控制器与Storyboard中的自定义容器视图控制器关联吗?

我可以将子视图控制器链接到选项卡视图控制器,并且可以将一个视图控制器链接到导航控制器。

我必须做什么容器风险投资接受儿童风险投资?

作为Caleb和Matt的答案的组合,我做了:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"cpdc_check_embed"]) { self.checkVC = segue.destinationViewController; } } 

…其中checkVC是容器控制器上的一个属性:

 @property (weak,nonatomic) PXPCheckViewController * checkVC; 

您只需将您的embed Segue的Storyboard ID为任何您想要的(在本例中为cpdc_check_embed ):

在Xcode中检查嵌入屏幕

…然后在-prepareForSegue:sender:检查标识符。

它仍然不是一个出口,但比马特(恕我直言)清洁,比迦勒的更具体,你仍然得到一个漂亮的故事板:

在这里输入图像说明

故事板非常好地处理内置的容器视图控制器,向子/视图控制器显示segues,以便清晰地显示关系。 孩子和家长视图控制器如何分离成不同的场景也是很好的。

如果你想在你自己的项目中达到这个效果,那么有一个技巧是不完美的,但非常简单。 在我的例子中,假设我有一个容器视图控制器,就像一个标签栏控制器,只有两个选项卡,“左”和“右”。 我想有一个场景表示父视图控制器,两个单独的场景表示“左”子视图控制器和“右”子视图控制器。

即使这是不可能的,如果我可以在不同的场景中从容器视图控制器创buildIBOutlet到它的子元素,然后当显示我的容器视图控制器时,根据描述的规则设置父/子关系UIViewController文档 。 如果我们引用了我们的“左”和“右”子视图控制器,那么我们可以build立关系没有问题。

此引用问题的标准解决scheme是通过将Object出口拖放到容器视图控制器的场景中,然后将其类types指定为子视图控制器类的实例来创build对子视图控制器的引用。

为了让孩子们像苹果的内置容器一样分离出不同的场景,我们将使用不同的技巧。 首先,假设我们的容器类ContainerViewController声明了以下属性:

 @property (nonatomic, strong, readwrite) UIViewController *leftViewController; @property (nonatomic, strong, readwrite) UIViewController *rightViewController; 

在我们的故事板中,select代表“左”视图控制器的场景。 在属性检查器中,将视图控制器的identifier属性设置为"cvc_leftViewController" (“cvc_”是指ContainerViewController ,但实际上标识符可以是任何你想要的)。 为正确的视图控制器的场景做同样的事情,把它的标识符设置为"cvc_rightViewController"

现在将下面的代码插入到ContainerViewControllerviewDidLoad方法中:

 if (self.storyboard) { _leftViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"cvc_leftViewController"]; _rightViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"cvc_rightViewController"]; } 

当从故事板加载ContainerViewController ,它将从各自的场景中抓取“左”和“右”视图控制器,并通过其属性设置对它们的引用。 既然您已经控制了子视图控制器实例,那么您可以设置父/子关系。 要学习如何正确地引用UIViewController文档 。

这个窍门并不完美,并且有许多警告,但是如果你小心的话,你可以使它适合你的项目。

编辑:虽然这是完全不必要的,并不意味着任何东西,如果你真的想要从你的容器到你的子视图控制器的故事板显示连接就像苹果的内置容器,只需使用我的方法,然后设置在容器场景之间直接延伸到儿童场景,并且根本不执行那些段落。 现在一切都会正常工作,看起来也很漂亮。

您可以将子视图控制器与Storyboard中的自定义容器视图控制器关联吗?

我想你在这里问的是如何将一个场景中的视图控制器连接到不同场景中的视图控制器的出口。 我不认为这是可能的,也许是因为故事板机制可能没有同时加载故事板中的所有场景。

你可能会问这个,因为你想从一个视图控制器传递一些信息到另一个视图控制器。 在处理故事板时,这样做的方法是在一个或两个受segue影响的视图控制器中重写-prepareForSegue:sender: segue参数中提供的UIStoryboardSegue对象具有sourceViewControllerdestinationViewController属性,还有一个identifier属性。 您可以使用这些属性来识别即将在视图控制器之间传输数据的Segue。

雷文德里克的博客有一个很好的两部分教程使用故事板,可以帮助你:

  • 第1部分包括设置故事板项目,添加场景和创build赛段。

  • 第2部分介绍如何在场景之间转换使用segues,包括上面提到的prepareForSeque方法。

iOS 5允许多个视图控制器在同一场景中处于活动状态(尽pipe仍然应该负责),因此故事板中的单个场景可能有多个控制器。 您可以使用sockets将这些控制器相互连接,并且可以按照您在IB中所做的相同方式configuration这些连接:在同一场景中,从一个控制器拖动到另一个控制器。 通常的sockets列表将popup以让您select要连接的sockets。

在一个场景中使用多个控制器(我相信你是在这里)的关键是使用来自IB的对象列表中的神秘对象来表示另一个视图控制器并且连接它的sockets。

这个答案如何使用iOS 5中的故事板创build自定义视图控制器容器应该帮助我希望。 答案还提供了一个有用的示例应用程序。

@ Ben的(否则合理的)答案的问题是它只能在一个嵌套层次上工作。 除此之外,它会要求每个后续的VC都被定制,以将嵌套视图控制器保存在prepareForSegue中。

为了解决这个问题,我花了太多的时间去研究一个基于NSObject的索引,你可以添加到Storyboard中,绑定到一个场景,然后根据types和restoreId将它的父VC注册到全局索引中。 这个工作/可以工作,但最终是太多的努力,并仍然需要两个步骤的过程中进行可视化绑定,并以编程方式查找。

对我来说,最简单和最一般的解决scheme是懒惰地下降视图控制器层次结构

在我简单的testing项目中,我添加了以下几行到viewDidLoad:

  self.left.data = [ "Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro.", "De carne lumbering animata corpora quaeritis." ] 

其中left定义为:

 lazy var left:CollectionViewController = { [unowned self] in return self.childViewControllerWithId("Left") as! CollectionViewController }() 

childViewControllerWithId被定义为:

 extension UIViewController { func childViewControllerWithId(rid:String) -> UIViewController? { // check immediate child controllers for vc in self.childViewControllers as! [UIViewController] { if vc.restorationIdentifier == rid { return vc } } // check nested controllers for vc in self.childViewControllers as! [UIViewController] { if let vc = vc.childViewControllerWithId(rid) { return vc } } assert(false, "check your assumptions") return nil } } 

请注意,如果需要,您可以根据types进行其他find变体。 另外请注意,以上要求您在故事板文件中定义恢复ID。 如果你没有重复的视图控制器的实例,那么使用types会更容易。

并且要陈述什么是希望显而易见的,您不需要执行prepareForSegue,也不必使用延迟加载,您只需调用find(...)