从父视图控制器中访问容器视图控制器 iOS
问题出现的原因是需要在父视图控制器中访问容器视图控制器。解决方法是通过在prepareForSegue方法中获取segue对象,并设置容器视图控制器的引用。
在Swift编程中,可以通过以下方式实现:
var containerViewController: ExampleViewController?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// 你可以在storyboard中的'segue.embed'中设置这个名称
if segue.identifier == "checkinPopupIdentifierInStoryBoard" {
let connectContainerViewController = segue.destinationViewController as ExampleViewController
containerViewController = connectContainerViewController
}
}
在上述代码中,通过prepareForSegue方法获取segue对象,并通过segue的identifier属性来判断是否是目标segue。如果是目标segue,则将segue的destinationViewController强制转换为ExampleViewController,并将其赋值给containerViewController。
在问题中的代码中,问题出现在if语句中的问号。问号的作用是可选链式调用的语法,用于判断一个可选类型是否包含值。在这里,如果segue.identifier为nil,则不会执行if语句内部的代码。这样可以避免在segue.identifier为nil时出现运行时错误。
因此,问题中的问号的作用是判断segue.identifier是否有值。如果有值,则执行if语句内部的代码,即将segue.destinationViewController强制转换为ExampleViewController,并将其赋值给containerViewController。如果没有值,则不执行if语句内部的代码。
希望通过这篇文章能够帮助你理解如何从父视图控制器中访问容器视图控制器,并解决问题中的疑问。
在iOS中,我们可以使用segue来访问子视图控制器(以及其视图和子视图)。在Storyboard中使用属性检查器给segue一个标识符(如alertview_embed
),然后让父视图控制器(包含容器视图的视图控制器)实现一个像这样的方法:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSString * segueName = segue.identifier; if ([segueName isEqualToString: @"alertview_embed"]) { AlertViewController * childViewController = (AlertViewController *) [segue destinationViewController]; AlertView * alertView = childViewController.view; // 在这里处理AlertView的子视图... } }
我们没有进行segue吗?我有什么遗漏吗...?
是的,当第二个视图控制器成为第一个视图控制器的子视图控制器时,会发生一个嵌入的segue。prepareForSegue:方法在这之前被调用。你可以利用这个机会传递数据给子视图控制器,或者存储对子视图控制器的引用以供后续使用。详情可参考developer.apple.com/library/ios/#documentation/uikit/reference/…
啊,对了,当视图加载时,“第二个视图控制器成为第一个视图控制器的子视图控制器”是指什么?现在我更明白了,谢谢。我现在不在我的项目中,但稍后会进行测试。
确切地说,它在viewDidLoad之前被调用。在viewDidLoad被调用时,父视图控制器和子视图控制器已经连接起来,父视图控制器中的[self childViewControllers]将返回一个包含所有子视图控制器的数组(参见下面rdelmar的答案)。
对于所提出的解决方案,我想加一个注意事项:在访问(子)目标视图控制器的view属性时要非常小心:在某些情况下,这会导致其viewDidLoad立即被调用。我建议在viewDidLoad安全地触发之前设置任何需要的segue数据。
可以解释一下这行代码吗.. AlertView * alertView = childViewController.view; "AlertView"是指什么?这是父视图控制器吗?抱歉,我对iOS还不熟悉。
不需要将其转换为AlertViewController,因为destinationViewController属性返回的是一个id类型。
在prepareForSegue中,我们可以使用isKindOfClass
而不是使用任意的字符串进行比较。
但是,.Emmons - 在Storyboard中命名segue是标准操作。如果prepareForSegue()中有其他类型的segue,目标控制器类型相同,但可能是不同的实例,那么你希望能知道哪个是哪个,segue的id就是解决这个问题的方法。也许在现实生活中不会发生这种情况,但无论如何... 在Swift中进行类型检查的方式如下:if segue.destinationViewController is <containingViewControllerClass> { self.containerController = segue.destinationViewControler as <containingViewContollerClass }
关于奇怪的术语“segue”的解释在这里:stackoverflow.com/a/23403979/294884