我的情况是子视图控制器正在尝试显示多个视图控制器,而在执行该子视图控制器时需要从父视图控制器访问播放暂停操作方法。如何实现这种可以实现暂停音频播放器,暂停计时器和暂停层的暂停动作方法:self.view.layer并在父视图控制器中定义,可以由childviewcontroller使用。
我将非常感谢您提供各种帮助来解决这个问题。
由于
答案 0 :(得分:9)
您可以使用parentViewController
属性访问视图控制器的父级。
if([self.parentViewController isKindOfClass:[SomeViewController class]]) {
SomeViewController* viewController = (SomeViewController*)self.parentViewController;
[viewController foo];
}
但是,这取决于视图控制器之间的关系。从你的问题,我推断你与多个孩子有亲子关系,但如果我错了请纠正我!这与模态视图控制器演示非常不同,在演示中只显示一个视图控制器,它需要用户立即关注。
<强>解释强>
UIViewController上的parentViewController
和presentingViewController
属性之间的区别似乎有些混乱。有两种不同的视图控制器关系,每种关系适用于其中一个属性。
如果您希望将多个视图控制器的视图添加为父视图控制器的子视图,请使用view controller containment。在这种情况下,作为父视图控制器的子视图(子级)添加的任何视图将在访问parentViewController
属性时返回父视图控制器(控制子视图的超级视图;父视图)。在这种情况下,presentingViewController
属性返回null
。
例如,在父视图控制器中:
- (void)viewDidLoad {
[super viewDidLoad];
SomeViewController* someVC = [[SomeViewController alloc] init];
[self addChildViewController:someVC];
[self.view addSubview:someVC.view];
[someVC.view setFrame:<SOME_FRAME>];
[someVC didMoveToParentViewController:self];
AnotherViewController* anotherVC = [[AnotherViewController alloc] init];
[self addChildViewController:anotherVC];
[self.view addSubview:anotherVC.view];
[anotherVC.view setFrame:<ANOTHER_FRAME>];
[anotherVC didMoveToParentViewController:self];
/* this prints self */
NSLog(@"%@", someVC.parentViewController);
/* this prints null */
NSLog(@"%@", someVC.presentingViewController);
/* this prints self */
NSLog(@"%@", anotherVC.parentViewController);
/* this prints null */
NSLog(@"%@", anotherVC.presentingViewController);
}
相反,如果您只想呈现单个模态视图控制器(比上面的一对多父子关系更常见的情况),则使用presentingViewController
属性。 / p>
例如,在呈现视图控制器中:
- (void)someActionTriggered {
SomeViewController* viewController = [[SomeViewController alloc] init];
[self presentViewController:viewController animated:YES completion:nil];
/* this prints null */
NSLog(@"%@", viewController.parentViewController);
/* this prints self, or a tab bar controller if 'self' is contained in one */
NSLog(@"%@", viewController.presentingViewController);
}
虽然由于iOS中模态视图控制器模式的普遍存在可能会更常见presentingViewController
,但视图控制器的视图控制器包含父子关系绝对合法,而parentViewController
和从iOS 5开始,UIViewController的childViewController
属性 not 已被弃用,它们的使用刚刚改变。您可以从文档中阅读此摘录:
<强>讨论强>
如果收件人是容器视图控制器的子级,则此属性包含其所包含的视图控制器。如果收件人没有父级,则此属性中的值为nil。
在iOS 5.0之前,如果视图没有父视图控制器并且正在呈现,则将返回呈现视图控制器。在iOS 5上,不再出现此行为。而是使用presentViewController属性来访问呈现视图控制器。
答案 1 :(得分:1)
每个视图控制器都有一个名为presentingViewController
的属性(如果ViewController1呈现模态呈现ViewController2,则ViewController1呈现为ViewController2的presentingViewController
)。
ViewController *viewController = (ViewController *)self.presentingViewController;
[viewController function];
另一种选择是使用NSNotificationCenter
。然后,您可以从应用程序中的任何位置轻松调用父视图控制器的方法。
ParentViewController.m
-(void)viewDidLoad {
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(method) name:@"Toggle Play" object:nil];
}
ChildViewController.m
[[NSNotificationCenter defaultCenter] postNotificationName:@"Toggle Play" object:nil];
答案 2 :(得分:1)
ParentViewController.h
-(void)PlayMusic;
ParentViewController.m
-(IBAction)PlayMusic:(id)sender {
[self playMusic];
}
在子视图控制器上的Play按钮的IBAction
处执行以下操作:
-(IBAction)PlayMusic:(id)sender {
ParentViewController *parent=self.parentViewController;
[parent playMusic];
}
答案 3 :(得分:0)
即使父母是UINavigationController
或UIViewController
使用以下内容,您也可以从子级访问父级:
self.parentViewController
你可以像这样上去
self.parentViewController!.parentViewController as! PARENT_VIEW_CONTROLLER