Question

I have a modal view controller that I called in from another view controller. Upon dismissal of the modal view controller, I want a method to be called on the view controller that presented that modal view. What is the easiest way to do this?

I tried doing this in my modal view controller: [(ParentViewController*)self.presentingViewController foo]; before calling [self dismissViewControllerAnimated:YES completion:nil];.

Xcode gives me an error saying foo isn't recognized, even though it is defined and prototyped in the controller. If your solution involves blocks, I really don't understand them so I would appreciate it if you would add more detail. Thanks.

ParentViewController.h

@interface ParentViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
{
    NewAssignmentViewController *newAssignmentViewController;
    TableViewDataSource *data;
}

-(void)foo;

@end
Was it helpful?

Solution

You need to get a correct reference to your presenting controller like this:

ParentViewController *presenter = [(UITabBarController *)self.presentingViewController viewControllers][0]; // 0 is assuming that ParentViewController is in the first tab. Change if necessary
[presenter foo];

The other way to do it would be to use delegation, but that's an answer for another time.

OTHER TIPS

If you are using a Storyboard segue to present your view controller you could dismiss it using an Unwind Segue. An unwind segue is a special kind of segue that unwinds the presented view controllers back to a presenter.

To accomplish this, you would create a method in the presenting view controller with the following signature:

- (IBAction)unwindAction:(UIStoryboardSegue*)unwindSegue;

This is different than a standard IBAction because the parameter type is a UIStoryboardSegue* instead of the normal id type (it doesn't have to be named unwindSegue:, it could be modalViewFinished: or whatever you like - the important part is that it has a return type of IBAction and a parameter type of UIStoryboardSegue*).

Once you have this method defined, in your storyboard you control-drag from the modal view controller icon (below its view, in the little bar of icons) and release the connection on the green exit sign. This will create an unwind segue, which you should give an identifier in the attributes inspector. Unwind segues will not show up visually in the storyboard canvas, so you will have to find it in the list of items on the left side of the canvas (this is collapsed by default, expand it by clicking the little circular button in the lower left hand corner of the canvas).

Once you've done that, rather than calling [self dismissViewControllerAnimated:YES completion:nil], just call [self performSegue:<Identifier you gave the unwind segue>] instead. During this process the unwindAction: method defined on the presenting view controller and the prepareForSegue: method on the modal view controller should be invoked. You can do whatever cleanup you need to do in these methods (calling the foo method from unwindSegue:, for example).

You call the method on the UIViewController that is your MainView, and pass it your UIViewController you want to be the ActionSheet.

UIActionSheet *actionSheetController =[[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"show otherview", nil];
 [self presentModalViewController:actionSheetController animated:YES ];

To dismiss the UIActionSheet, dimissWithClickedButtonIndex:animated: is a method for the UIActionSheet that you can implement. The method can be called by whoever (so if you want to dismiss it from your mainview have a reference to the action sheet and do something like

-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
{
        switch (buttonIndex){
            case 0:
            {
               [actionSheet dismissWithClickedButtonIndex:0 animated:YES];
            }
                break;

            case 1:
            {
                MyClass *myclassObject = [[MyClass alloc]init]; 
                [myclassObject foo];
            }
       }
}

The method is also called whenever the 'cancel' button is clicked by the user.

Use this ModalViewControllers link for better understanding...!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top