3

我有一种情况,子视图控制器试图显示多个视图控制器,并且在这样做时,子视图控制器需要从父视图控制器访问播放暂停操作方法。childviewcontroller 可以使用在父视图控制器中定义的暂停音频播放器、暂停计时器和暂停 layer:self.view.layer 的播放暂停操作方法是如何实现的。

我将非常感谢为解决此问题提供的各种帮助。

谢谢

4

4 回答 4

9

parentViewController您可以使用该属性访问视图控制器的父级。

if([self.parentViewController isKindOfClass:[SomeViewController class]]) {
    SomeViewController* viewController = (SomeViewController*)self.parentViewController;

    [viewController foo];
}

但是,这取决于您的视图控制器之间的关系。从你的问题,我推断你有多个孩子的亲子关系,但如果我错了,请纠正我!这与模态视图控制器演示非常不同,其中仅呈现一个视图控制器并且需要用户立即注意。

解释:

parentViewControllerUIViewController 上的和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 属性来访问呈现视图控制器。

于 2013-01-12T21:50:47.813 回答
1

ParentViewController.h

-(void)PlayMusic;

ParentViewController.m

-(IBAction)PlayMusic:(id)sender {
       [self playMusic];
}

IBAction子视图控制器上的播放按钮执行以下操作:

-(IBAction)PlayMusic:(id)sender {
       ParentViewController *parent=self.parentViewController;
       [parent playMusic];
}
于 2014-11-26T12:48:04.293 回答
1

每个视图控制器都有一个名为的属性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];
于 2013-01-13T00:48:31.343 回答
0

您可以从子级访问父级,即使父级是UINavigationControllerORUIViewController使用以下命令:

self.parentViewController

你可以像这样往上走

self.parentViewController!.parentViewController as! PARENT_VIEW_CONTROLLER
于 2016-09-10T20:19:28.290 回答