如何回到已加载的UIViewController?

46

我在一个故事板上有一个按钮,用于执行某个操作。但是要执行此操作,用户必须先登录。按钮处理程序会检查用户是否已登录,并根据结果执行相应的转场(segue)。如果已登录,它执行一个转场;如果未登录,则执行另一个转场将页面推到一个登录视图控制器。此外,还有另一个segue连接回第一个视图控制器,所以如果登录成功,用户可以继续之前的操作。这些视图控制器都嵌入在导航控制器中。

问题是,“返回”segue加载了整个新实例的视图控制器,而不是引用原始实例,因此界面元素为空,并且在内存中有两个该视图控制器的副本。

我如何返回到原始视图控制器的实例?

4个回答

136

假设你使用的是UINavigationController,那么通过以下方式可以返回到栈顶。

[self.navigationController popToRootViewControllerAnimated:YES];
或者
UIViewController *prevVC = [self.navigationController.viewControllers objectAtIndex:<n>];
[self.navigationController popToViewController:prevVC animated:YES];

弹出到特定的层级,其中<n>表示该层级。

或者

[self.navigationController popViewControllerAnimated:YES];

如果您只想弹出导航堆栈中的一个级别。


1
我有一个UIBarButton,最初是在上一个屏幕的ViewDidLoad中加载的(我们要返回到那个屏幕)。当我使用你的代码时,UIBar根本不显示。你有什么想法为什么会这样? - C0D3

33

不要使用segue返回到上一个控制器,而应该使用与返回segue相关联的事件来关闭当前视图控制器(如果segue是模态的),或者从导航控制器中弹出此控制器(如果segue是推动的),上一个控制器将自动显示。

例如,如果在登录屏幕上按下按钮时执行了模态segue返回操作,则应该从故事板中删除该segue,并在按钮的“touch up inside”事件上链接您的操作,以在成功登录后调用:

 [self dismissViewControllerAnimated:YES completion:nil];
在Storyboard中,您需要右键单击按钮并将“Touch Up Inside”事件拖动到视图控制器场景的第一响应者上。这将执行与执行segue转换时相反的转换。您可以使用模态segue进行此操作,无需使用导航控制器。
如果您将登录视图推送到导航控制器,则必须从堆栈中弹出它(如果返回到以前的视图)。使用以下其中之一:
    [[self navigationController] popViewControllerAnimated:YES];  // goes back to previous view
[[self navigationController] popToViewController: myViewControllerAfterLogin animated:YES]; // goes back to specific view on stack. 
[[self navigationController] popToRootViewControllerAnimated:YES]; // goes back to first view on the stack

动画过渡效果应该与转场时使用的过渡类型相反,所以当你关闭视图时,向上翻页会变成向下翻页。


如果您正在使用自定义segue,例如对于push segue而言不是滑动效果,那么pop将不会是您自定义segue的反向操作,而只是一个滑动效果。 - nenchev

5

2

马尔哈尔是正确的——点击他的链接是值得的。

这段代码似乎比苹果的示例更为灵活。我有三个场景,但只有一个自定义的ViewController .m文件。我不想要导航栈。通过按钮从segues访问后续场景。我在基本视图控制器.m文件中添加了这一行:

- (IBAction)unwindForSegue:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC{}

然后在第三个场景中,我通过从按钮拖动到退出图标并选择解开操作来控制。现在它会自动回到第二个场景而不需要调用dismissViewController方法。


我认为我最终理解的关键是,它会展开您的堆栈,直到到达实现与特定退出转场相关联的unwindAction的控制器。因此,您可以使用不同的unwind操作定义多个退出转场,然后在要着陆的控制器中实现每个转场的特定unwind操作。 - Andy Weinstein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接