最近在项目中遇到了一个比较棘手的需求:
1.无论当前在哪个页面,点击页面上某个按钮都要返回主页面
2.无论当前在哪个页面,点击页面上某个按钮都可以随意跳转到任意的二级页面
3.需要显示页面跳转动画
(当前页面可能是NavigationgController管理的也可能是Present 出来的)
根据以上需求的描述,首先第一步要做的就是拿到当前页面的根控制器,这里通常App页面都是采用NavigationController管理的,所以我们就以他作为例举了。
AppDelegate
*delegate = (
AppDelegate
*)[
UIApplication
sharedApplication].delegate;
UINavigationController *rootViewController = (UINavigationController *)delegate.window.rootViewController;
第二步需要判断当前在页面最顶端的Controller到底是由哪种类型的跳转出来的(目前页面的跳转主要就有两种 Pop和Present,稍作判断即可)。如果是Present出来的Controller,就直接Dismiss就好了
if
(rootViewController.
presentedViewController
) {
isPresentAnimation = YES ;
UIViewController * presentedViewController = rootViewController. presentedViewController ;
[presentedViewController dismissViewControllerAnimated : YES completion:^{
}];
isPresentAnimation = YES ;
UIViewController * presentedViewController = rootViewController. presentedViewController ;
[presentedViewController dismissViewControllerAnimated : YES completion:^{
}];
}
第三步 关掉了Present出来的Controller,结下来要做的就是搞定NavigationController。这里我们既要处理跳转到主页面,又要考虑跳转到任意的页面,所以穿参数的时候才用的是传入StroyboardName和Identify(页面如果用Storyboard管理的话,拿到相应的页面会容易很多)。然后判断当前压栈的Controller里面有没有我们要保留的页面,同时Pop出所有没用的页面,而后将我们要跳转的页面压栈到最顶端。最后,关键的来了,最核心的跳用方法来了,调用NavigationController的方法
setViewControllers
将当前的栈全部替换掉,同时加入Animaiton的bool值。即可
NSMutableArray
*controllerArray = [
NSMutableArray
arrayWithArray:rootViewController.viewControllers];
for (UIViewController *c in rootViewController.viewControllers) {
if ([c isMemberOfClass:[MainViewControllerclass]]
||[c isMemberOfClass:[RootViewControllerclass]]) {
continue;
}
[controllerArray removeObject:c];
}
[controllerArray addObject:controller];
for (UIViewController *c in rootViewController.viewControllers) {
if ([c isMemberOfClass:[MainViewControllerclass]]
||[c isMemberOfClass:[RootViewControllerclass]]) {
continue;
}
[controllerArray removeObject:c];
}
[controllerArray addObject:controller];
[rootViewController setViewControllers:controllerArray animated:!isPresentAnimation];
以上的代码完全可以完成需求的跳转,但是还是存在如下的缺点待完善:
1.当前跳转指定的页面只能是NavigationController管理的,而且职能跳转二级页面。对于Present出来的页面还没有考虑
2.不能处理多层Present出来的页面