21

I have some code to clean up in my viewWillDisappear:, which I only want to use when the view is moving back to the parent view controller.

- (void)viewWillDisappear:(BOOL)animated
{
    if ([self isMovingFromParentViewController] || [self isBeingDismissed]) {
        NSLog(@"isMovingFromParentViewController or isBeingDismissed");
        // clean up
    }
    [super viewWillDisappear:animated];
}

The view can be presented in two ways: it can be pushed by a navigation controller, or presented as a modal view controller (from the same navigation controller). If it's pushed, then popped (pressing the back button), my clean-up code runs. If it it presented as a modal view controller, then dismissed, the code doesn't run.

I dismiss like so:

[rootViewController dismissModalViewControllerAnimated:YES];

My question is: why isn't isBeingDismissed set when I dismiss my view controller?

nevan king
  • 112,709
  • 45
  • 203
  • 241

5 Answers5

35

If this is the first view controller in a modal navigation controller that's being dismissed, calling self.isBeingDimissed() from viewWillDisappear: returns false.

However, since the entire navigation controller is being dismissed, what actually works is self.navigationController?.isBeingDismissed(), which returns true.

Beau Nouvelle
  • 6,962
  • 3
  • 39
  • 54
Yuval Tal
  • 645
  • 7
  • 12
24

As @Yuval Tal mentioned, this flag does not work when you're dismissing controller that is embeded inside navigation controller. Here's an extension that I use:

extension UIViewController 
{
    var isAboutToClose: Bool {
        return self.isBeingDismissed ||      
               self.isMovingFromParent ||          
               self.navigationController?.isBeingDismissed ?? false
    }
}

It can be easily extended when you find another case when standard .isBeingDismissed won't work. And if you find, let us, let me know in comments.

Ahmadreza
  • 6,950
  • 5
  • 50
  • 69
Kubba
  • 3,390
  • 19
  • 34
5

Your issue is how you are dismissing your modal view. How is rootViewController being defined?

When I call [self dismissModalViewControllerAnimated:YES] then [self isBeingDismissed] evaluates to true.

When I call [parentViewController dismissModalViewControllerAnimated:YES] then [self isBeingDismissed] evaluates to true, whereby parentViewController is the UIViewController that presented the modal view (note: not a UINavigationController).

Dilip Manek
  • 9,095
  • 5
  • 44
  • 56
Joel
  • 15,654
  • 5
  • 37
  • 60
  • 6
    I can confirm that `isBeingDismissed()` returns `false` when the viewController is supposedly popped from a `UINavigationController`, such as the detail viewController in a collapsed `UISplitViewController`. – bio Nov 04 '15 at 17:24
4

If by some chance you came here trying to use isBeingDismissed on a non-modally presented view controller, you can always check the topViewController property of your navigationController, for instance:

if navigationController?.topViewController != self {
    return
}
eLillie
  • 653
  • 9
  • 17
0
        viewController.isBeingPresented == NO;
        [rootVC presentViewController:viewController animated:NO completion:^{
            viewController.isBeingPresented == NO;
            viewController.isBeingDismissed == NO;
            [viewController dismissViewControllerAnimated:NO completion:^{
                viewController.isBeingDismissed == NO;
            }];
            viewController.isBeingDismissed == NO;    // is not work
        }];
        viewController.isBeingPresented == YES;     // is work
        viewController.isBeingPresented == NO;
        [rootVC presentViewController:viewController animated:NO completion:^{
            viewController.isBeingPresented == NO;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                viewController.isBeingDismissed == NO;
                [viewController dismissViewControllerAnimated:NO completion:^{
                    viewController.isBeingDismissed == NO;
                }];
                viewController.isBeingDismissed == YES;    // is work
            });
        }];
        viewController.isBeingPresented == YES;     // is work
diong
  • 71
  • 2