从容器视图的视图控制器中,如何访问包含容器的视图控制器?
这是棘手的字,但我有一个视图控制器(vc1),其中包含一个容器视图(我正在使用故事板)。 在该容器视图内是一个导航控制器和一个根视图控制器(vc2)。
从vc2中,我怎样才能访问vc1?
或者,我如何将vc1传递给vc2? (请记住,我正在使用故事板)。
您可以使用Vc1中的prepareForSegue
方法,因为当ContainerViewController成为子对象时会发生嵌套。 您可以将自己作为obj传递或存储对孩子的引用以供以后使用。
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSString * segueName = segue.identifier; if ([segueName isEqualToString: @"embedseg"]) { UINavigationController * navViewController = (UINavigationController *) [segue destinationViewController]; Vc2 *detail=[navViewController viewControllers][0]; Vc2.parentController=self; } }
编辑:小代码修复
要从您的子视图控制器访问父视图控制器,您必须覆盖didMoveToParentViewController :
- (void)didMoveToParentViewController:(UIViewController *)parent { [super didMoveToParentViewController:parent]; //Use parent }
在Xcode Command +点击这个方法的更多信息:
在子控制器之间转换时,这两个方法是公用的,用于调用容器子类。 如果他们被覆盖,覆盖应确保打电话给超级。 这两个方法中的父参数是零,当一个孩子被从其父母移除; 否则等于新的父视图控制器。
addChildViewController:在添加子项之前将调用[child willMoveToParentViewController:self]。 但是,它不会调用didMoveToParentViewController :. 预期一个容器视图控制器的子类将在转换到新的subprocess之后进行调用,或者在没有转换的情况下,在调用addChildViewController之后: 同样,removeFromParentViewController:在移除子项之前不会调用[self willMoveToParentViewController:nil]。 这也是容器子类的责任。 容器子类通常会定义一个方法,通过首先调用addChildViewController来转换到新的子类,然后执行一个转换,将新的子视图添加到其父视图层次结构中,最后调用didMoveToParentViewController :. 同样,子类通常会定义一个方法,通过首先调用[child willMoveToParentViewController:nil]以相反的方式删除子元素。
使用属性parentViewController
作为self.parentViewController
您可以使用Bonnie使用的相同方法使用委派。 这是你如何做到的:
在你的containerViews ViewController中:
class ContainerViewViewController: UIViewController { //viewDidLoad and other methods var delegate: ContainerViewControllerProtocol? @IBAction func someButtonTouched(sender: AnyObject) { self.delegate?.someDelegateMethod() //call this anywhere } } protocol ContainerViewControllerProtocol { func someDelegateMethod() }
在你的父级ViewController中:
class ParentViewController: UIViewController, ContainerViewControllerProtocol { //viewDidLoad and other methods override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "filterEmbedSegue" { let containerViewViewController = segue.destinationViewController as ContainerViewViewController containerViewViewController.delegate = self } } func someDelegateMethod() { //do your thing } }
谢谢邦妮告诉我该怎么做。 事实上,为赛格方法做准备是最好的select。
我只是澄清代码和步骤在这里。
所以首先,在连接容器视图和第一个视图控制器的故事板中命名segue(链接)。 我把我的名字命名为“toContainer”。
然后在包含容器视图的视图控制器中添加这个方法
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString: @"toContainer"]) { UINavigationController *navViewController = (UINavigationController *) [segue destinationViewController]; UIViewController *vc2 = [navViewController viewControllers][0]; } }
所以vc2是我想要参考的控制器。
这工作对我来说,如果你的第一个viewconroller不是一个导航控制器,你的方法会在prepareForSegue里面稍有不同。
1)在VC2上暴露一个传入一个引用VC1的属性
//VC2.h #import "VC1.h" @interface VC2 : NSObject @property (strong, nonatomic) VC1 *parent; @end
2)在VC1上,将自己的标识符设置为“ToVC2”之后,将自己传递给prepareForSegue方法中VC2中暴露的属性。 然后像这样传递参考:
//VC1.m @implementation VC1 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if([segue.identifier isEqualToString:@"ToVC2"]) { VC2 *vc2 = segue.destinationViewController; vc2.parent = self; } }