我正在使用Storyboard开发一个应用程序。此应用程序要求用户登录。
Storyboard 首次登录视图。当登录正常时,它会执行到 TabViewController 的segue。
在对API的任何调用中,我检查服务器是否返回401(未授权)。如果发生这种情况,则将布尔值设置为false(boolean isLogged)。 AppDelegate观察到这个布尔值。如果value更改为false,我想将用户返回到登录屏幕(请记住,Storyboard上的初始视图)。
以下是一些代码:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"isLogged"]) {
BOOL logged = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
if (logged) {
NSLog(@"Logged in succesfully!");
} else {
NSLog(@"Logout performed");
[self.window makeKeyAndVisible];
[self.window layoutSubviews];
}
}
这很好用,但是当我再次尝试登录 LoginOK 时,不执行segue。
我尝试了很多其他选项,如下所示:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:@"Login"];
[source presentModalViewController:loginController animated:YES];
但问题是我不知道哪个View Controller执行了注销。 Source必须是应用程序中显示的当前View Controller,不是吗?
答案 0 :(得分:3)
最后,我解决了将 isLogged 的观察者从App Delegate更改为我的自定义 TabViewController 的问题。在 viewDidLoad 中,我订阅了这个var。
在方法 observeValueForKeyPath 中,我执行以下操作:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
LoginViewController *loginController = [storyboard instantiateViewControllerWithIdentifier:@"Login"];
[self presentModalViewController:loginController animated:YES];
答案 1 :(得分:2)
我以为我会和你分享这个相当随意的想法。
如果您没有将登录屏幕设置为视图层次结构中的必要步骤,但是只要应用程序状态需要登录,从任何普通视图控制器以模态方式显示,该怎么办。这就是什么模态视图控制器用于 - 不要让用户恢复正常流程,直到满足一些明确的先决条件。
通过这种方式,您不必担心将整个导航堆栈展开到初始控制器。保存状态也要容易得多,因为一旦成功执行身份验证,用户就应该能够恢复正常的工作流程,而不是重新开始。
只是一个想法。
更新#1:
一种选择是使用自定义通知来执行登录是必需的状态。您必须让所有视图控制器观察通知,当前可见的控制器将执行模态视图控制器的显示。
您可以使用此代码borrowed from here来检查视图控制器实例是否可见:
if (viewController.isViewLoaded && viewController.view.window) {
// viewController is visible
}