Detect when a presented view controller is dismiss

2019-02-04 01:45发布

Let's say, I have an instance of a view controller class called VC2. In VC2, there is a "cancel" button that will dismiss itself. But I can't detect or receive any callback when the "cancel" button got trigger. VC2 is a black box.

A view controller (called VC1) will present VC2 using presentViewController:animated:completion: method.

What options does VC1 have to detect when VC2 was dismissed?

Edit: From the comment of @rory mckinnel and answer of @NicolasMiari, I tried the following:

In VC2:

-(void)cancelButton:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:^{

    }];
//    [super dismissViewControllerAnimated:YES completion:^{
//        
//    }];
}

In VC1:

//-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
- (void)dismissViewControllerAnimated:(BOOL)flag
                           completion:(void (^ _Nullable)(void))completion
{
    NSLog(@"%s ", __PRETTY_FUNCTION__);
    [super dismissViewControllerAnimated:flag completion:completion];
//    [self dismissViewControllerAnimated:YES completion:^{
//        
//    }];
}

But the dismissViewControllerAnimated in the VC1 was not getting called.

13条回答
【Aperson】
2楼-- · 2019-02-04 02:02

I've seen this post so many times when dealing with this issue, I thought I might finally shed some light on a possible answer.

If what you need is to know whether user-initiated actions (like gestures on screen) engaged dismissal for an UIActionController, and don't want to invest time in creating subclasses or extensions or whatever in your code, there is an alternative.

As it turns out, the popoverPresentationController property of an UIActionController (or, rather, any UIViewController to that effect), has a delegate you can set anytime in your code, which is of type UIPopoverPresentationControllerDelegate, and has the following methods:

Assign the delegate from your action controller, implement your method(s) of choice in the delegate class (view, view controller or whatever), and voila!

Hope this helps.

查看更多
相关推荐>>
3楼-- · 2019-02-04 02:03

overrideing viewDidAppear did the trick for me. I used a Singleton in my modal and am now able to set and get from that within the calling VC, the modal, and everywhere else.

查看更多
不美不萌又怎样
4楼-- · 2019-02-04 02:05

Use a Block Property

Declare in VC2

var onDoneBlock : ((Bool) -> Void)?

Setup in VC1

VC2.onDoneBlock = { result in
                // Do something
            }

Call in VC2 when you're about to dismiss

onDoneBlock!(true)
查看更多
Melony?
5楼-- · 2019-02-04 02:05

You can use unwind segue to do this task, no need to use the dismissModalViewController. Define an unwind segue method in your VC1.

See this link on how to create the unwind segue, https://stackoverflow.com/a/15839298/5647055.

Assuming your unwind segue is set up, in the action method defined for your "Cancel" button, you can perform the segue as -

[self performSegueWithIdentifier:@"YourUnwindSegueName" sender:nil];

Now, whenever you press the "Cancel" button in the VC2, it will be dismissed and VC1 will appear. It will also call the unwind method, you defined in VC1. Now, you know when the presented view controller is dismissed.

查看更多
Juvenile、少年°
6楼-- · 2019-02-04 02:06

@user523234 - "But the dismissViewControllerAnimated in the VC1 was not getting called."

You can't assume that VC1 actually does the presenting - it could be the root view controller, VC0, say. There are 3 view controllers involved:

  • sourceViewController
  • presentingViewController
  • presentedViewController

In your example, VC1 = sourceViewController, VC2 = presentedViewController, ?? = presentingViewController - maybe VC1, maybe not.

However, you can always rely on VC1.animationControllerForDismissedController being called (if you have implemented the delegate methods) when dismissing VC2 and in that method you can do what you want with VC1

查看更多
登录 后发表回答