7
votes

I was just knew that the completion block in the self.presentViewController(childVc, animated: true, completion: {}) is called after the child view controller is finish getting animated to be displayed at the screen. I actually want to run a block of code that get displayed after the animation of child view controller is finished getting animated to be dismissed. How can I do that, preferrably avoiding using delegate to do that?

EDIT: I call this from the presented (child) view controller like this: self.presentingViewController.dismissViewControllerAnimated (true) {}, but the problem is the child view controller can be presented from arbitrary page, and after the child is dismissed, the parent (presenting) view controller has to do different things. If I implement the call back in the child, I can't do different thing with different parent that call it.

For example, if I call login form as modal in the news screen, after the login form dismissed, I want to display comment section afterwards. But if the login form modally displayed from product screen, I want to display the user's cart with the product in the cart afterwards. If this is impossible to be done without delegate, I still interested in the delegate solution.

4

4 Answers

10
votes

You can add a property to your ChildVC to store a callback closure and set this when you present the child view controller. When the child view controller dismisses itself it can call the completion handler:

class ChildVC: UIViewController {        
    var completionHandler : ((childVC:ChildVC) -> Void)?

    func dismiss() {
        self.dismissViewControllerAnimated(true) {
            self.completionHandler?(childVC:self)
        }
    }
}

You supply the completion handler when you present the ChildVC instance:

let completionHandler:(ChildVC)->Void = { childVC in
    print("completed for \(childVC)")
}
childVC.completionHandler=completionHandler
self.presentViewController(childVC, animated: true, completion: nil)
1
votes

Use dismissViewControllerAnimated API which takes a completion block.

    self.dismissViewControllerAnimated(true) { 
        /* Do callback stuff here*/
    }
1
votes

You can create a callback block in presented ViewController like that @property(nonatomic,copy)void (^onDimissed)();
and after in presented view controller call
[self dismissViewControllerAnimated:YES completion:^{ if (self.onDismissed) { self.onDismissed(); } }];
So you can return any params in block
And don't forget make this
SomeController *ctr = [[UIViewController alloc] init]; ctr.onDimissed = ^{ //some your implementation };

-1
votes

If you using self.presentingViewController.dismissViewControllerAnimated (true) {} this return nil why means its not support all the OS, so simply use this below code,

self.dismissViewControllerAnimated(true, completion: {
   //Put your code
});

if you dismiss the ViewController you can call any function put your code in completion handler.

hope its helpful