一些场景需要把一切跳转干掉,回到根视图!(一位大佬写的,俺只是搬运工😄)
思路1:root有3种可能 1.控制器 2拥有导航栏的控制器 3是tabBar控制器
思路2:首先理解presentedViewController presentingViewController visibleViewController这3个属性
思路3:我们可以拿到root所对应的控制器跟当前的最上层进行比较,如果不一样,说明显示层不是root,不是root那我们则需要把前面一长串跳转干掉,如何完美的干掉这一长串呢?我们知道dismiss这个方法有个代码块,这就说明了该方法存在延迟性,如果一层一层的dismiss那么是有可能出问题的。
-
思路3:既然不能一层一层的进行dismiss那么我们可以换一种思路,拿到当前显示层后一层一层往下找,直到该控制器没有下一层时我们直接拿该控制器进行dismiss就可以了,nav就使用popToRoot!
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> typedef NS_ENUM(NSUInteger, AnimationType) { AnimationTypeBottom, AnimationTypeLeft, }; @interface JumpVCManager : NSObject @property (nonatomic,strong) UIViewController* rootVC; + (instancetype)shareInstance; - (void)backToRootVCAnimation:(AnimationType)type; - (void)backToRootVC; - (UIViewController *)visibleVC; @end #import "JumpVCManager.h" @interface JumpVCManager() @property (nonatomic) BOOL isJumping;// 是否正在跳转 @end @implementation JumpVCManager + (instancetype)shareInstance{ static JumpVCManager *_shareInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _shareInstance = [[self alloc] init]; }); return _shareInstance; } - (UIViewController *)rootVC{ UIViewController *rootViewcontroller = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; UIViewController *rootVC = rootViewcontroller; if ([rootViewcontroller isKindOfClass:[UITabBarController class]]) { UITabBarController *tabVC = (UITabBarController*)rootViewcontroller; if ([tabVC.selectedViewController isKindOfClass:[UINavigationController class]]) { rootVC = [(UINavigationController*)(tabVC.selectedViewController) viewControllers][0]; } else { rootVC = tabVC.selectedViewController; } } else if ([rootViewcontroller isKindOfClass:[UINavigationController class]]) { UINavigationController *nav = (UINavigationController *)rootViewcontroller; rootVC = nav.viewControllers[0]; } return rootVC; } - (void)backToRootVCAnimation:(AnimationType)type{ [self addAnimationWithType:type]; [self backToRootVC]; } - (void)addAnimationWithType:(AnimationType)type{ CATransition *animation = [CATransition animation]; //动画时间 animation.duration = 0.25f; //过滤效果 animation.type = kCATransitionReveal; //动画执行完毕时是否被移除 animation.removedOnCompletion = YES; animation.subtype = kCATransitionFromBottom; if (type == AnimationTypeLeft) { animation.subtype = kCATransitionFromLeft; } [[UIApplication sharedApplication].keyWindow.layer addAnimation:animation forKey:nil]; } - (void)backToRootVC{ if (self.isJumping == NO) { self.isJumping = YES; NSLog(@"start"); [self backToRootViewController]; } } - (void)backToRootViewController{ NSLog(@"bbbbbbbbbbbbbbb"); UIViewController* vc = [self visibleVC]; if ([vc isEqual:self.rootVC]) { NSLog(@"end"); self.isJumping = NO; return; } if (vc.presentingViewController) { while (vc.presentingViewController) { vc = vc.presentingViewController; } [vc dismissViewControllerAnimated:NO completion:^{ [self backToRootViewController]; }]; } else{ [vc.navigationController popToRootViewControllerAnimated:NO]; [self backToRootViewController]; } } - (UIViewController *)visibleVC{ UIViewController *rootViewController =[[[[UIApplication sharedApplication] delegate] window] rootViewController]; return [JumpVCManager getVisibleViewControllerFrom:rootViewController]; } + (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc { if ([vc isKindOfClass:[UINavigationController class]]) { return [JumpVCManager getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]]; } else if ([vc isKindOfClass:[UITabBarController class]]) { return [JumpVCManager getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]]; } else { if (vc.presentedViewController) { return [JumpVCManager getVisibleViewControllerFrom:vc.presentedViewController]; } else { return vc; } } } @end