Shabarinath Pabba Shabarinath Pabba - 2 months ago 7
iOS Question

Intercept when a user navigates to a new view controller

I am working on an app where I will need to figure out if a user moved to a new viewcontoller, this would include if a new view controller is presented or when you come back to an earlier view controller, I have tried implementing this with a UIViewController category and intercepting user navigating to a page by overriding "viewDidAppear", but I don't want to use a category to do this as there is a high impact on every view controller, is there any way I would be able to do this?

Example: So we are working on sharing ur app screen to a customer service rep, a rep has his own rules for example there are 2 pages in an application, when customer is sharing his app screen and is on page 1, I will check the rules and figure out whether the rep should see the page and when customer navigates to page 2 and rep doesn't have permission to view this, I will pause the screen sharing because I realized page 2 is not in rep's permissions and now when I go back to page 1, I will need to check permissions again and show the page to rep(essentially resuming the screen sharing)

Answer

I fixed this by the following, I have a "CADisplayLink" as the following

I create properties

@property(nonatomic, strong) UIViewController *topViewController;//This will essentially be the visible view controller at any time
@property(nonatomic, strong) CADisplayLink *displayLink;

then I instantiate the "displayLink"

self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(checkTopViewController)];
self.displayLink.frameInterval = 2;//I want the refresh rate to be slower than with the UI refresh rate
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

- (void)checkTopViewController{
    UIViewController *vc = [self findBestViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
    if (self.topViewController != vc) {
        self.topViewController = vc;
        //Top visible view controller changed
    }
}

-(UIViewController*) findBestViewController:(UIViewController*)vc {

    if (vc.presentedViewController) {

        // Return presented view controller
        return [UIViewController findBestViewController:vc.presentedViewController];

    } else if ([vc isKindOfClass:[UISplitViewController class]]) {

        // Return right hand side
        UISplitViewController* svc = (UISplitViewController*) vc;
        if (svc.viewControllers.count > 0)
            return [UIViewController findBestViewController:svc.viewControllers.lastObject];
        else
            return vc;

    } else if ([vc isKindOfClass:[UINavigationController class]]) {

        // Return top view
        UINavigationController* svc = (UINavigationController*) vc;
        if (svc.viewControllers.count > 0)
            return [UIViewController findBestViewController:svc.topViewController];
        else
            return vc;

    } else if ([vc isKindOfClass:[UITabBarController class]]) {

        // Return visible view
        UITabBarController* svc = (UITabBarController*) vc;
        if (svc.viewControllers.count > 0)
            return [UIViewController findBestViewController:svc.selectedViewController];
        else
            return vc;

    } else {

        // Unknown view controller type, return last child view controller
        return vc;

    }

}