我们在非视图类中想要随时展示一个view时,需要将被展示的view加到当前view的子视图,或需要 presentViewController,或pushViewContrller,这些操作都需要获取当前正在显示的ViewController。
发觉百度搜出来好多不科学的方法,有时候还是自己动脑子想好。。。
下面提供了一个公用的方法去获取当前ViewController,也建议直接改成静态方法,放到工具类里直接调用更加科学。
具体代码如下:
//获取当前屏幕显示的viewcontroller
- (UIViewController *)getCurrentVC
{
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
UIViewController *currentVC = [self getCurrentVCFrom:rootViewController];
return currentVC;
}
- (UIViewController *)getCurrentVCFrom:(UIViewController *)rootVC
{
UIViewController *currentVC;
if ([rootVC presentedViewController]) {
// 视图是被presented出来的
rootVC = [rootVC presentedViewController];
}
if ([rootVC isKindOfClass:[UITabBarController class]]) {
// 根视图为UITabBarController
currentVC = [self getCurrentVCFrom:[(UITabBarController *)rootVC selectedViewController]];
} else if ([rootVC isKindOfClass:[UINavigationController class]]){
// 根视图为UINavigationController
currentVC = [self getCurrentVCFrom:[(UINavigationController *)rootVC visibleViewController]];
} else {
// 根视图为非导航类
currentVC = rootVC;
}
return currentVC;
}
解析:代码主要使用了递归的思想(哈哈哈,毕业工作半年,发觉第一次写iOS用到递归,突然觉得高大上)。
[UIApplication sharedApplication].keyWindow.rootViewController获取到的是项目的根视图,结合可能用到UITabBarController或者UINavigationController作为导航结构,以及可能present出新的VC,其实如果用storyboard的方式写UI的话就很清晰,类似树的结构,再利用递归找到当前视图。
ps:
如果是需要push新的视图,就很简单啦:
用上面的方法获取到顶层的视图,判断currentVC.navigationController是否为nil。(为nil,则新建UINavigationController在push;否则直接用currentVC.navigationController去push)
ps2:
补充评论里好的建议,如果用到的场景主要是vc里,可以弄成类别如下:
#import "UIViewController+Helper.h"
@property (nonatomic, strong ,readonly) UIViewController * _Nullable currentVC;
//当前屏幕显示的viewcontroller
-(UIViewController *)currentVC{
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
UIViewController *controller = [self getCurrentVCFrom:rootViewController];
return controller;
}
//getCurrentVCFrom参考上文
还有什么不懂的就留言问问哈。。。。
网友评论
// 视图是被presented出来的
rootVC = [rootVC presentedViewController];
}
这里应改为if ([rootVC presentedViewController]) {
// 视图是被presented出来的
return [self getCurrentVCFrom:rootvc. presentedViewController];
}
否则不能获取到多次present的vc
建一个控制器类别
#import "UIViewController+Helper.h"
@property (nonatomic, strong ,readonly) UIViewController * _Nullable currentVC;
//当前屏幕显示的viewcontroller
-(UIViewController *)currentVC{
UIViewController *rootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
UIViewController *controller = [self getCurrentVCFrom:rootViewController];
return controller;
}
也有另外用的场景,所以没弄成类别,我经常用于工具类或者appdelegate里。
if ([rootVC presentedViewController]) {
// 视图是被presented出来的
rootVC = [rootVC presentedViewController];
}
不过如果是要拿vc里的childViewController,应该支持不到,建议自己在方法里面做对应修改去获取。
// 视图是被presented出来的
rootVC = [rootVC presentedViewController];
}楼主这个没太明白.望解释下
这种方法挺好,如果要获取一个显示的vc的childViewController的话,还需要自己加代码。但如果这个vc有多个childVcs,那恐怕要分别给childVc加标记了,才能获取到精确的VC。
如果要获取一个显示的vc的childViewController的话,还需要自己加代码。但如果这个vc有多个childVcs,那恐怕要分别给childVc加标记了,才能获取到精确的VC。