How child view controller can use the method defin

2019-05-15 01:38发布

I have a situation where child view controller is trying to display multiple view controller and while doing that child view controller needs to access play pause action method from the parent view controller. How this can be achieved that play pause action method which is to pause audio player, pause timer and pause layer:self.view.layer and is defined in parent view controller can be used by childviewcontroller.

I will appreciate so much for all kinds of help to solve this.

Thanks

4条回答
SAY GOODBYE
2楼-- · 2019-05-15 02:03

You can access a view controller's parent with the parentViewController property.

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

    [viewController foo];
}

However, this depends on the relationship between your view controllers. From your question, I inferred that you had a parent-child relationship with multiple children, though please correct me if I am wrong! This is very different from a modal view controller presentation, in which only one view controller is presented and it demands the user's immediate attention.

Explanation:

There seems to be some confusion about the difference between the parentViewController and presentingViewController properties on UIViewController. There are two different view controller relationships, each of which applying to one of these properties.

If you wish to add multiple view controllers' views as subviews of a parent view controller, you use view controller containment. In this situation, any of the views added as subviews (children) of the parent view controller will return the parent view controller (which controls the superview of the children; the parent view) when the parentViewController property is accessed. In this situation, the presentingViewController property returns null.

For example, in the parent view controller:

- (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);
}

Contrarily, if you simply wish to present a single, modal view controller (a situation which is more common than the one-to-many parent-child relationship above), then the presentingViewController property is used.

For example, in the presenting view controller:

- (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);
}

Although presentingViewController might be seen more commonly due to the prevalence of the modal view controller pattern in iOS, the view controller containment parent-child relationship of view controllers is absolutely legitimate, and the parentViewController and childViewController properties of a UIViewController have not been deprecated as of iOS 5, their use has just changed. You can read this excerpt from the documentation:

Discussion

If the recipient is a child of a container view controller, this property holds the view controller it is contained in. If the recipient has no parent, the value in this property is nil.

Prior to iOS 5.0, if a view did not have a parent view controller and was being presented, the presenting view controller would be returned. On iOS 5, this behavior no longer occurs. Instead, use the presentingViewController property to access the presenting view controller.

查看更多
再贱就再见
3楼-- · 2019-05-15 02:10

You can access the Parent from the Child, even if the parent was UINavigationController OR UIViewController using the following:

self.parentViewController

and you can go upward like this

self.parentViewController!.parentViewController as! PARENT_VIEW_CONTROLLER
查看更多
闹够了就滚
4楼-- · 2019-05-15 02:12

Each view controller has a property called presentingViewController (if ViewController1 presents modally presents ViewController2, ViewController1 is ViewController2's presentingViewController).

ViewController *viewController = (ViewController *)self.presentingViewController;
[viewController function];

Another option is to use NSNotificationCenter. You can then easily call the parent view controller's method from anywhere in the app.

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];
查看更多
再贱就再见
5楼-- · 2019-05-15 02:24

At ParentViewController.h

-(void)PlayMusic;

At ParentViewController.m

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

At IBAction of Play Button on child view controller do this:

-(IBAction)PlayMusic:(id)sender {
       ParentViewController *parent=self.parentViewController;
       [parent playMusic];
}
查看更多
登录 后发表回答