-1

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)

Shabarinath Pabba
  • 1,359
  • 2
  • 13
  • 22
  • You should *NEVER* use categories to override existing methods: http://stackoverflow.com/questions/5272451/overriding-methods-using-categories-in-objective-c – vikingosegundo Sep 14 '16 at 18:59
  • @vikingosegundo thats exactly why I do not want to do that and trying to find a different solution, so honestly speaking I need to be able to intercept when topViewcontroller changes? I mean the visible view controller changing is what needs to be intercepted – Shabarinath Pabba Sep 14 '16 at 19:00
  • why dont you use a common UIViewController subclass that override viewDidAppear? another way that comes to my mind would be Aspect Oriented Programming. Several libraries for objective-c do exist. – vikingosegundo Sep 14 '16 at 19:05
  • @vikingosegundo I can't use UIViewController subclass because I already have about 200 Viewcontrollers in the app and I will have to go manually in to each class and add everything to be inherited from the base class – Shabarinath Pabba Sep 14 '16 at 19:13
  • 1
    I cannot imaging any app that needs 200 view controllers. I'd say that is a problem you should fix first. – vikingosegundo Sep 14 '16 at 19:15
  • its a banking application which also works on claims, loans, insurance and a lot of other stuff, there is a team of over 80 people working on this application and mostly our customers bank using the app or the website, so it has a lot of things – Shabarinath Pabba Sep 14 '16 at 19:17
  • Sounds like this team of 80 needs a software architect. let me guess: your view controllers are also huge and do implement delegates and datasources. – vikingosegundo Sep 14 '16 at 19:20
  • no we try to stay away from that :D, its not a design honestly, its just a huge app, we try to have everything accessible through the app because our customers are mostly outside the country and can't visit a physical office location – Shabarinath Pabba Sep 14 '16 at 19:23
  • 1
    still: no need for 200 view controllers. read up [SOLID priciples](https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)), [Composition over inheritance](https://en.wikipedia.org/wiki/Composition_over_inheritance) and [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). I am sure that you have a lot of copy and pasted code and codes that could be reduced if properly parameterised. This is important as duplicated codes mean duplicated errors — something you dont want in a banking application. – vikingosegundo Sep 14 '16 at 19:27
  • btw: what is the name of the app? – vikingosegundo Sep 14 '16 at 19:28
  • there might be duplicated code in there, but definitely not the reason why we have so many view controllers, I think there are about 10-15 architects working on the design since 2008, the number of view controllers thing is definitely not avoidable for our app, different divisions in our company need different designs, u can basically think of us as though we have around 15 different companies within our company, so is there a way to do it without using inheritance? worse comes to worse I can always base class i and have every other base view controller inherit from mine – Shabarinath Pabba Sep 14 '16 at 19:34
  • If inheritance in an OO language isn't an option, something is very very wrong. Besides that I named another approach. AOP. ask google "objective-c AOP" and you will find a lot. – vikingosegundo Sep 14 '16 at 19:39
  • or bad architects :p – Shabarinath Pabba Sep 14 '16 at 20:04
  • well, that's the same. – vikingosegundo Sep 14 '16 at 20:04
  • @vikingosegundo so I used CADisplayLink, to see if the topViewcontroller is changing, I seemed to achieve what I needed. Do you think thats a good idea? – Shabarinath Pabba Sep 22 '16 at 14:49
  • can you post it ans an answer, with code? – vikingosegundo Sep 22 '16 at 14:52
  • @vikingosegundo added – Shabarinath Pabba Sep 22 '16 at 17:25

1 Answers1

1

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;

    }

}
Shabarinath Pabba
  • 1,359
  • 2
  • 13
  • 22