Is there a general best-practices way of being notified when the current view controller is being dismissed (either popped or dismissModalDialog'd)? I can't use -viewWillDisappear:, since that also gets called when another viewController is pushed atop the current one.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        [self addObserver:self forKeyPath:@"parentViewController" options:0 context:NULL];
    }
    return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([@"parentViewController" isEqualToString:keyPath] && object == self) {
        if (!self.parentViewController)
            NSLog(@"Dismissed");
    }
}
- (void)dealloc
{
    [self removeObserver:self forKeyPath:@"parentViewController"];
    [super dealloc];
}
                        Apple changed how presentation is working in iOS8, they are using presentationControllers, because presentationControllers are not KVO compilant, i had to use containerView because it is removedFromSuperview and nilled when -[UIPresentationController transitionDidFinish:] is called. Solution for iOS8 and above:
self.presentationContext.presentViewController(self.viewControllerToPresent, animated: true, completion: { _ in
     self.viewControllerToPresent.presentationController?.addObserver(self, forKeyPath: "containerView", options: [], context: &self.observingContext)
})
I am adding observer is completionHandler because presentation can fail sometimes especially when presenting on already presenting viewController.
In observer value i have to remove observation when containerView no longer exists:
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
    guard &self.observingContext == context else {
        super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
        return
    }
    if let presentationController = object as? UIPresentationController where presentationController.containerView == nil {
        presentationController.removeObserver(self, forKeyPath: "containerView")
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With