In my viewDidAppear, how do I know when it's being unwound by a child?

前端 未结 6 1340
一向
一向 2021-01-01 13:36

When my child performs an unwind segue, my controller\'s viewDidAppear gets called.

In this method (and this method alone, I need to know whether it was from an unwi

6条回答
  •  猫巷女王i
    2021-01-01 14:22

    Here is a simple category on UIViewController that you can use to track whether your presented view controller is in the midst of an unwind segue. I suppose it could be flushed out more but I believe this much works for your case.

    To use it you need to register the unwind segue from your unwind action method on the destination view controller:

    - (IBAction) prepareForUnwind:(UIStoryboardSegue *)segue
    {
        [self ts_registerUnwindSegue: segue];
    }
    

    That's it. From your intermediate view controller, you can test if you are in the midst of an unwind segue:

    - (void) viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear: animated];
    
        BOOL unwinding = [self ts_isUnwinding];
    
        NSLog( @"%@:%@, unwinding: %@", self.title, NSStringFromSelector(_cmd), unwinding ? @"YES" : @"NO" );
    }
    

    There's no need to clean anything up; the segue will self-deregister when it ends.

    Here's the full category:

    @interface UIViewController (unwinding)
    
    - (void) ts_registerUnwindSegue: (UIStoryboardSegue*) segue;
    - (BOOL) ts_isUnwinding;
    
    @end
    
    
    static NSMapTable* g_viewControllerSegues;
    
    @implementation UIViewController (unwinding)
    
    - (void) ts_registerUnwindSegue: (UIStoryboardSegue*) segue
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
    
            g_viewControllerSegues = [NSMapTable weakToWeakObjectsMapTable];
        });
    
        for ( UIViewController* vc = segue.sourceViewController ; vc != nil ; vc = vc.presentingViewController )
        {
            [g_viewControllerSegues setObject: segue forKey: vc];
        }
    }
    
    - (BOOL) ts_isUnwinding
    {
        return [g_viewControllerSegues objectForKey: [self ts_topMostParentViewController]] != nil;
    }
    
    - (UIViewController *)ts_topMostParentViewController {
        UIViewController *viewController = self;
        while (viewController.parentViewController) {
            viewController = viewController.parentViewController;
        }
        return viewController;
    }
    
    @end
    

提交回复
热议问题