如何从多重 modalViewController 中直接返回最底层

ModalViewController是经常会用到的展现ViewController的方式,而显示和收起ModalViewController也是很简单的

1
2
3
4
5
6

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0);
- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);

- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0);
- (void)dismissModalViewControllerAnimated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0);

但是有的时候我们的需求很特殊,比如在一个ModalViewController里要present另一个ModalViewController,甚至再present一个ModalViewController,然后可能在某个时候APP发出一条消息,需要一下子dismiss掉所有的ModalViewController(比如你在使用过程中,突然APP检测到你的登录状态异常,需要重新登录,这个时候所有的页面都需要消失),这时候该如何办呢?

正巧我现在正在做的项目遇到了这个问题,所以研究了一下,得到了以下的解决办法:

首先,必须知道现在整个APP最顶层的ViewController是哪个,我的做法是在每个ViewControllerviewWillAppear中记录一下,当然这个操作是自动完成的,因为每个项目,我都会从UIViewController派生一个子类,然后再从这个子类派生所有的ViewController方便管理.

1
2
3
4
5
6
7
8
9
10
11
12

@interface MMViewController : UIViewController

@end

@implementation MMViewController

- (void)viewWillAppear:(BOOL)animated
{
APP.presentingController = self;
}
@end

得到了顶层的ViewController以后,事情就简单了,我们只要追根溯源,找到最底层的ViewController就行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

if ( APP.presentingController )
{
UIViewController *vc = self.presentingController;

if ( !vc.presentingViewController )
{
return;
}

while (vc.presentingViewController)
{
vc = vc.presentingViewController;
}

[vc dismissViewControllerAnimated:YES completion:^{

}];

}