在 iOS 8 上导航到上一个场景

Posted

技术标签:

【中文标题】在 iOS 8 上导航到上一个场景【英文标题】:Navigation to previous scene on iOS 8 【发布时间】:2015-01-20 21:08:54 【问题描述】:

我正在开发一个需要对后端进行身份验证的 ios 8 应用程序。我想以这样的方式制作应用程序,如果应用程序收到 HTTP 403 错误,则会向用户显示登录屏幕。在登录屏幕视图控制器成功验证用户身份后,应用程序应导航回上一个屏幕(无论它是什么屏幕)。

在 Xcode 6 中,我可以看到在场景之间导航的首选方式是通过 segue。因此,我使用 segues 从登录屏幕导航回来,代码如下:

[self performSegueWithIdentifier:@"UnwindToNewsfeed" sender:self];

这带来的问题是,我必须为应用程序中的所有场景建立 segues,因为它们中的任何一个都可能触发身份验证请求。因此,我想寻求一种推荐的方法来实现此导航要求。

我是 iOS8 和 iPhone 编程的新手,所以可能是我没有完全清楚 iOS 8 的导航概念,而且我使用了错误的方法。

【问题讨论】:

【参考方案1】:

Unwind segues 与 forward segues 不同,这使得支持您所追求的功能变得非常简单。

在创建展开转场之前,您需要向要展开的视图控制器添加一个方法。例如 -

- (IBAction)unwindFromLogin:(UIStoryboardSegue*)sender 

然后,您可以通过在场景中的对象(或场景的 UIViewController 对象,如果您想使用performSegueWithIdentifier 触发展开)和屏幕底部的退出图标之间拖动来创建展开转场. Interface Builder 将显示它找到的与上面签名匹配的方法列表(因此它将显示unwindFromLogin:)。你可以给这个 segue 一个标识符,这样你就可以像往常一样使用performSegueWithIdentifier 调用它。到目前为止一切顺利。

现在,为了聪明一点。在运行时调用 unwind segue 时,iOS 会查看当前视图控制器堆栈以找到第一个实现指定方法的视图控制器 - 因此,如果您在每个视图控制器中实现相同的 unwindFromLogin: 方法,您的登录视图将展开到它来自的视图控制器,您只需要在登录视图控制器场景中进行一次展开转场。

Apple 有一个很好的 Tech Note,它更详细地描述了展开过程以及如何通过在 UIViewController 子类中实现其他方法来自定义它,但默认实现应该适合您的需要。

如果您不想创建从每个源视图控制器到登录视图控制器的转场,您可以使用类似 -

的方式直接呈现它
LoginViewController *loginVC=(LoginViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"loginVC"];
[self presentViewController:loginVC animated:YES completion:nil];

你仍然可以使用 unwind segue 返回

【讨论】:

感谢你们两位的全面回答。难题中仍然缺少的是,如何实现从每个屏幕到登录屏幕的导航?我是否必须在 IB 中构建从每个场景到登录场景的转场,或者是否有更简单的编程方式将此行为构建到场景中?【参考方案2】:

我不认为使用 segues 总是最好的方法。在这种情况下,使用-popToViewController:animated: 可能会更好。

也就是说,在这里使用 unwind 仍然可以工作。我建议创建一个子类UIViewController 的自定义视图控制器。这个视图控制器实现了你的-unwindXXX: 方法。

@interface MYBaseViewController : UIViewController
- (IBAction)unwindXXX:(UIStoryboardSegue *)sender;
…
@end

让所有可以从登录视图控制器展开的视图控制器都继承这个自定义视图控制器。

@interface MYNewsFeedViewController : MYBaseViewController
…
@end

【讨论】:

【参考方案3】:

我认为下面的两个答案是有效的,我都投了赞成票。

但是,经过测试,我发现这种方法对我的场景来说更简单且不那么麻烦。

在任何可以触发登录提示的屏幕上,我通过调用以下方法强制显示登录屏幕:

LoginViewController *loginView = [self.storyboard instantiateViewControllerWithIdentifier:@"LoginView"];
[self presentViewController:loginView animated:YES completion:nil];

然后,为了启用用户在登录界面成功认证后所需的后退导航功能,登录界面调用该方法,返回预览场景:

[self dismissViewControllerAnimated:YES completion:nil];

由于我是 iOS 开发新手,我不确定这是否遵循推荐的做法,所以我希望人们评论这是否是推荐的方法。

【讨论】:

以上是关于在 iOS 8 上导航到上一个场景的主要内容,如果未能解决你的问题,请参考以下文章

iOS 6,StroryBoards:在模态转场后更新主场景上的 UITextView

SpriteKit,创建一个位于所有场景之上的导航菜单

如何在 Swift iOS 中仅在最后一个屏幕上获取导航栏?

Xcode - iOS - 要更改的导航控制器场景顺序

iOS:SWRevealViewController 打开没有导航栏的 WebView 控件

导航到上一个视图控制器,默认后退按钮不起作用