2

我正在使用 Storyboards 开发一个应用程序。此应用程序要求用户登录。

故事初始时有一个登录视图。当登录正常时,​​它对TabViewController执行 segue 。

在对 API 的任何调用中,我都会检查服务器是否返回 401(未授权)。如果发生这种情况,则将布尔值设置为 false(布尔 isLogged)。AppDelegate 观察这个布尔值。如果值更改为 false,我想将用户返回到登录屏幕(请记住,故事板上的初始视图)。

这是一些代码:

- (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 执行了注销。源必须是应用程序中显示的当前视图控制器,不是吗?

4

2 回答 2

3

我想我会和你分享这个相当随机的想法。

如果您没有将登录屏幕作为视图层次结构中的重要步骤,而是在应用程序状态需要登录时立即从任何普通视图控制器以模态方式呈现它会怎样。这就是模态视图控制器的用途 - 不让用户恢复正常流程,直到满足某些明确的先决条件。

通过这样做,您不必担心将整个导航堆栈展开到初始控制器。保存状态也容易得多,因为一旦成功执行身份验证,用户应该能够恢复她的正常工作流程,而不是重新开始。

只是一个想法。

更新#1:

一种选择是使用自定义通知来携带登录是必需的状态。您必须让所有视图控制器都观察通知,而当前可见的视图控制器将执行模态视图控制器的呈现。

您可以使用从这里借来的代码来检查视图控制器实例是否可见:

if (viewController.isViewLoaded && viewController.view.window) {
    // viewController is visible
}
于 2012-07-01T18:11:37.687 回答
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];
于 2012-07-01T23:15:25.367 回答