我有一个表视图控制器A,它对视图控制器B执行推送segue。我在 C 上有一个按钮,它需要导致 C 被解雇(如前所述是模态的)以及 B 的弹出,以便我们回到 A。在 C 中,我检测到按钮按下并使用委托回调 B,然后使用以下命令关闭模态视图控制器 C:
[sender dismissViewControllerAnimated:NO completion:nil];
然后,B 使用委托回调 A,A使用以下方法从堆栈中弹出 B:
[self.navigationController popViewControllerAnimated:YES];
现在这一切都有效,除了一个非常烦人的事实,即我在所有这些过程中短暂地看到了 B,而我希望能够从 C 直接"弹出"到 A,而根本没有看到 B,无论多么短暂。我已经尝试了上述动画参数的YES/NO组合,也尝试了popToRootViewControllerAnimated,但没有运气:-(
有人有什么想法吗?
我拼凑了一个快速的项目,使用这段代码对我来说似乎工作得很好:
[self dismissViewControllerAnimated:YES completion:nil];
// Just a coincidence that this is the presenting VC rather than a regular UIViewController I think.
UINavigationController *navController = (UINavigationController *)self.presentingViewController;
[navController popViewControllerAnimated:NO];
这是Github上的示例项目:https://github.com/MaxGabriel/iOSNavigationFlow
[self.navigationController popViewControllerAnimated:NO];
您可以使用以下代码执行所需的操作。首先,你弹出 ToRootViewController,它将控制器 B 从堆栈中移除,但不会更改视图,因为 C 的视图已打开。然后,将导航控制器的视图添加到 C 的视图下方,使其位于视图层次结构中,但不可见。然后,执行动画以将 C 的视图向右滑动,最后关闭模式视图控制器。我创建了一个属性 nav 来缩短键入时间,但这并不是真正必要的。此代码位于模态视图控制器的 .m 中
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.nav = (UINavigationController *)self.presentingViewController;
}
-(IBAction)goBackToRoot: (UIButton *) sender {
[self.nav popToRootViewControllerAnimated:NO];
[self.view.window insertSubview:self.nav.view belowSubview:self.view];
[UIView animateWithDuration:.6 animations:^{
self.view.frame = CGRectMake(330, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
} completion:^(BOOL finished) {
[self.nav dismissViewControllerAnimated:NO completion:nil];
}];
}
在 iOS 6 中,如果您使用展开 segue,则不会获得那种奇怪的效果。在要跳回的视图控制器中,只需定义一个展开操作:
- (IBAction)home:(UIStoryboardSegue *)segue
{
// if you need to do any UI update because we got an unwind segue
// back to this controller, do that here
}
然后在您呈现的视图控制器(它可以向下多个级别)可以通过从启动 segue 的按钮向下拖动到场景停靠栏中的"退出"图标来执行展开 segue。它将自动浏览、识别和呈现具有展开操作的视图控制器,并呈现这些选择。
最终效果是,您可以跳回多个模态和导航控制器,并且只能获得一种动画效果。
同样,可悲的是,这只是iOS 6 +。