IOS Learning -- get the current top-level ViewController and iosviewcontroller
During iOS development, we often need to obtain the ViewController of the current page, and then use ViewController to perform some operations, such as displaying a UIAlertController on the top-level ViewController, you can also present another ViewController on the top-level ViewController or perform other operations.
1. Implementation
The bottom-layer ViewController is used to search up until the top-layer ViewController is found, that is, the rootViewController of the keyWindow of the UIApplication is found. (If there are multiple uiwindows, The UIWindow selection should be considered.
In the search process, consider the current ViewController is UITabBarController and UINavigationController respectively, and also consider whether the current ViewController uses presentViewController: animated: completion: mode to display other viewcontrollers.
2. Method 1:
- (UIViewController *)topViewController { UIViewController *resultVC; resultVC = [self _topViewController:[[UIApplication sharedApplication].keyWindow rootViewController]]; while (resultVC.presentedViewController) { resultVC = [self _topViewController:resultVC.presentedViewController]; } return resultVC;}- (UIViewController *)_topViewController:(UIViewController *)vc { if ([vc isKindOfClass:[UINavigationController class]]) { return [self _topViewController:[(UINavigationController *)vc topViewController]]; } else if ([vc isKindOfClass:[UITabBarController class]]) { return [self _topViewController:[(UITabBarController *)vc selectedViewController]]; } else { return vc; } return nil;}
Usage:
UIViewController *topmostVC = [self topViewController];
Method 2:
// Obtain the viewcontroller-(UIViewController *) getCurrentVC {UIViewController * rootViewController = [UIApplication sharedApplication] displayed on the current screen. keyWindow. rootViewController; UIViewController * currentVC = [self getCurrentVCFrom: rootViewController]; return currentVC;}-(UIViewController *) getCurrentVCFrom :( UIViewController *) rootVC {UIViewController * currentVC; if ([rootVC presentedViewController]) {// The view is a presented rootVC = [rootVC presentedViewController];} if ([rootVC isKindOfClass: [UITabBarController class]) {// The Root View is UITabBarController currentVC = [self getCurrentVCFrom: [(UITabBarController *) rootVC selectedViewController];} else if ([rootVC isKindOfClass: [UINavigationController class]) {// The Root View is UINavigationController currentVC = [self getCurrentVCFrom: [(UINavigationController *) rootVC visibleViewController];} else {// The Root View is a non-navigation class currentVC = rootVC ;} return currentVC ;}
Analysis:
The Code mainly uses the recursive idea.(Hahaha, half a year after graduation, I found that the first time I wrote iOS, I used recursion. I suddenly felt very tall ).
[UIApplication sharedApplication]. keyWindow. rootViewController obtains the project Root View.Combined with the possible use of UITabBarController or UINavigationController as the navigation structure, and may present a new VC. In fact, if you use storyboard to write the UI, it is very clear, similar to the tree structure, use recursion to find the current view.
Ps:If you need to push a new view, it is very simple. Use the above method to obtain the top-level view and determine whether currentVC. navigationController is nil. (Nil, create UINavigationController, and then push; otherwise, use currentVC. navigationController to push directly ). Three extensions
If the main application scenario is in vc, the following categories can be used:
# Import "UIViewController + Helper. h "@ property (nonatomic, strong, readonly) UIViewController * _ Nullable currentVC; // viewcontroller-(UIViewController *) currentVC {UIViewController * rootViewController = [UIApplication sharedApplication] displayed on the current screen. keyWindow. rootViewController; UIViewController * controller = [self getCurrentVCFrom: rootViewController]; return controller;} // getCurrentVCFrom refer to the above two methods