开发者

Method called when dismissing a UIViewController?

开发者 https://www.devze.com 2022-12-22 18:13 出处:网络
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

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 cal开发者_JS百科led 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")
    }
}


As far as I know there's no automatic way to get notified, but since UIViewController has a modalViewController property, you could define a like "didDismiss...", and call that method on the previous modal view controller after presenting your new modal view controller.


Can you clarify you question?

I'm thinking that you're asking:

ViewcontrollerONE pops up ViewControllerTWO modally. ViewControllerTWO is dismissed. ViewControllerONE wants to know that That ViewControllerTWO just dismissed itself, and wants to run XYZ method because of it.

I don't have a good answer, but I do have a way:

VC1 is simply referenced in VC2. so VC2 can notify VC1 before dismissal.


The selected answer using KVO did not work for me on iOS 8.

I subclassed UIViewController as follows and then I just call dismissAnimated:completion: on the presented view controller instead of dismissViewControllerAnimated:completion:. I register for observing the notification elsewhere and trigger handling as needed.

#define DismissNotifyViewControllerDismissedNotification  @"DismissNotifyViewControllerDismissed"


@interface DismissNotifyViewController : UIViewController

- (void)dismissAnimated:(BOOL)flag completion:(void (^)(void))completion;

@end


@implementation DismissNotifyViewController

- (void)dismissAnimated:(BOOL)flag completion:(void (^)(void))completion
{
    [self.presentingViewController dismissViewControllerAnimated: flag
                                                      completion: ^{

          if (completion)
               completion();

          [NSNotificationCenter.defaultCenter 
                     postNotificationName: DismissNotifyViewControllerDismissedNotification
                     object: self];
    }];
}

@end
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号