我有一种情况,子视图控制器试图显示多个视图控制器,并且在这样做时,子视图控制器需要从父视图控制器访问播放暂停操作方法。childviewcontroller 可以使用在父视图控制器中定义的暂停音频播放器、暂停计时器和暂停 layer:self.view.layer 的播放暂停操作方法是如何实现的。
我将非常感谢为解决此问题提供的各种帮助。
谢谢
我有一种情况,子视图控制器试图显示多个视图控制器,并且在这样做时,子视图控制器需要从父视图控制器访问播放暂停操作方法。childviewcontroller 可以使用在父视图控制器中定义的暂停音频播放器、暂停计时器和暂停 layer:self.view.layer 的播放暂停操作方法是如何实现的。
我将非常感谢为解决此问题提供的各种帮助。
谢谢
parentViewController
您可以使用该属性访问视图控制器的父级。
if([self.parentViewController isKindOfClass:[SomeViewController class]]) {
SomeViewController* viewController = (SomeViewController*)self.parentViewController;
[viewController foo];
}
但是,这取决于您的视图控制器之间的关系。从你的问题,我推断你有多个孩子的亲子关系,但如果我错了,请纠正我!这与模态视图控制器演示非常不同,其中仅呈现一个视图控制器并且需要用户立即注意。
解释:
parentViewController
UIViewController 上的和presentingViewController
属性之间的区别似乎有些混乱。有两种不同的视图控制器关系,每一种都适用于这些属性之一。
如果您希望将多个视图控制器的视图添加为父视图控制器的子视图,请使用视图控制器包含。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
使用该属性。
例如,在呈现视图控制器中:
- (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);
}
尽管presentingViewController
由于模式视图控制器模式在 iOS 中的流行可能会更常见,但视图控制器包含父子关系是绝对合法的,并且UIViewController的parentViewController
和属性在 iOS 5 中还没有被弃用,它们的用途刚刚改变。您可以从文档中阅读以下摘录:childViewController
讨论
如果接收者是容器视图控制器的子级,则此属性保存它所在的视图控制器。如果接收者没有父级,则此属性中的值为 nil。
在 iOS 5.0 之前,如果视图没有父视图控制器并且正在呈现,则将返回呈现视图控制器。在 iOS 5 上,此行为不再发生。相反,使用presentingViewController 属性来访问呈现视图控制器。
在ParentViewController.h
-(void)PlayMusic;
在ParentViewController.m
-(IBAction)PlayMusic:(id)sender {
[self playMusic];
}
在IBAction
子视图控制器上的播放按钮执行以下操作:
-(IBAction)PlayMusic:(id)sender {
ParentViewController *parent=self.parentViewController;
[parent playMusic];
}
每个视图控制器都有一个名为的属性presentingViewController
(如果 ViewController1 以模态方式呈现 ViewController2,则 ViewController1 是 ViewController2 的presentingViewController
)。
ViewController *viewController = (ViewController *)self.presentingViewController;
[viewController function];
另一种选择是使用NSNotificationCenter
. 然后,您可以从应用程序的任何位置轻松调用父视图控制器的方法。
父视图控制器.m
-(void)viewDidLoad {
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(method) name:@"Toggle Play" object:nil];
}
ChildViewController.m
[[NSNotificationCenter defaultCenter] postNotificationName:@"Toggle Play" object:nil];
您可以从子级访问父级,即使父级是UINavigationController
ORUIViewController
使用以下命令:
self.parentViewController
你可以像这样往上走
self.parentViewController!.parentViewController as! PARENT_VIEW_CONTROLLER