Reputation: 13588
How do I get reference to top visible view controller in my app. I saw some solutions which make use of navigationcontroller.[top|visible]viewcontroller. But I don't use navigation controllers in my app.
This seems like a pretty common use case, and I find it strange it is difficult to get access to top|visible view controller
Upvotes: 1
Views: 3974
Reputation: 1
-(UIViewController *) getTopMostController
{
UIWindow *topWindow = [UIApplication sharedApplication].keyWindow;
if (topWindow.windowLevel != UIWindowLevelNormal)
{
topWindow = [self returnWindowWithWindowLevelNormal];
}
UIViewController *topController = topWindow.rootViewController;
if(topController == nil)
{
topWindow = [UIApplication sharedApplication].delegate.window;
if (topWindow.windowLevel != UIWindowLevelNormal)
{
topWindow = [self returnWindowWithWindowLevelNormal];
}
topController = topWindow.rootViewController;
}
while(topController.presentedViewController)
{
topController = topController.presentedViewController;
}
if([topController isKindOfClass:[UINavigationController class]])
{
UINavigationController *nav = (UINavigationController*)topController;
topController = [nav.viewControllers lastObject];
while(topController.presentedViewController)
{
topController = topController.presentedViewController;
}
}
return topController;
}
-(UIWindow *) returnWindowWithWindowLevelNormal
{
NSArray *windows = [UIApplication sharedApplication].windows;
for(UIWindow *topWindow in windows)
{
if (topWindow.windowLevel == UIWindowLevelNormal)
return topWindow;
}
return [UIApplication sharedApplication].keyWindow;
}
Upvotes: 0
Reputation: 1
-(UIViewController *)getCurrentViewController
{
UIViewController *result = nil;
UIWindow * window = [[UIApplication sharedApplication] keyWindow];
if (window.windowLevel != UIWindowLevelNormal)
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow * tmpWin in windows)
{
if (tmpWin.windowLevel == UIWindowLevelNormal)
{
window = tmpWin;
break;
}
}
}
UIView *frontView = [[window subviews] objectAtIndex:0];
id nextResponder = [frontView nextResponder];
if ([nextResponder isKindOfClass:[UIViewController class]])
result = nextResponder;
else
result = window.rootViewController;
return result;
}
Upvotes: 0
Reputation: 2564
This should also follow your modal views and navigation controllers (if any):
- (UIViewController *)deepestPresentedViewControllerOf:(UIViewController *)viewController
{
if (viewController.presentedViewController) {
return [self deepestPresentedViewControllerOf:viewController.presentedViewController];
} else {
return viewController;
}
}
- (UIViewController *)topViewController
{
UIViewController *rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
UIViewController *deepestPresentedViewController = [self deepestPresentedViewControllerOf:rootViewController];
if ([deepestPresentedViewController isKindOfClass:[UINavigationController class]]) {
return ((UINavigationController *)deepestPresentedViewController).topViewController;
} else {
return deepestPresentedViewController;
}
}
Upvotes: 3
Reputation: 385500
You should probably be using the delegate pattern here (giving the child view controller a reference to an object that it can call on). If you edit your post to explain why you think you need a reference to the top view controller, we can give you advice about how to use the delegate pattern in your situation.
But for now I'll just give you the rope you need to hang yourself:
UIViewController *topVC = [UIApplication sharedApplication].keyWindow.rootViewController;
Upvotes: 1