2013-07-19 185 views
0

所以,我有我的应用程序中是否没有逻辑,基于用户的凭据的问题,我的应用程序的主视图应显示在主视图中的tableview登录视图已被驳回或只显示后登录视图后的主视图已被解除。视图控制器堆栈

所以现在,我发送一个HTTP POST请求从哪里获得令牌回来,然后让之后的另一个调用来获取用户拥有的列表项数量的服务器,可以说游戏。

如果用户只有一个游戏,我想要显示主视图,但是如果用户有多个游戏,那么用户应该看到一个tableview,按下其中一个单元然后以模式方式解除tableview显示主视图。

通常我有这3个控制器,至少这是我正在考虑实施应该怎样,不知道它的正确的方式的方式。

所以假定控制器A是登录,控制器B是的tableview,和控制器C是MAINVIEW。

控制器C位于堆栈的底部,而控制器A位于顶部。但是,潜在地,控制器B可能会或可能不会基于来自控制器A的信息显示。当我说栈底时,我的意思是如果用户还没有登录,那么登录视图(控制器A)将被呈现在主视图(控制器C)上没有动画。所以在技术上,主视图(控制器C)总是被加载,但数据没有被提供给它,只有在登录视图被正确提交的凭证解除之后。

以下是在mainviewcontroller(控制器C)中实施的一些方法,用于检查用户是否已登录,如果没有,则应用程序技术上会首先通过mainviewcontroller并呈现登录视图。我明白,这是去与应用开发的登录模式的方法,但我不是100%:

- (void)showLoginViewAnimated:(BOOL)animated { 
    NSLog(@"[MainViewController] Show login view controller"); 
    PowerOneLoginTabBar *loginVC = [[PowerOneLoginTabBar alloc] init]; 
    [self presentViewController:loginVC animated:NO completion:nil]; 
} 

- (void)logoutHandler:(NSNotification *)notification { 
    NSLog(@"[MainViewController] Logout handler"); 
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"userLoggedIn"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 

    [self showLoginViewAnimated:YES]; 
} 

在MAINVIEW的viewDidLoad中(视图 - 控制C):

BOOL isUserLoggedIn = [[NSUserDefaults standardUserDefaults] boolForKey:@"userLoggedIn"]; 
    if(!isUserLoggedIn || (!setAuthenticationKey || [setAuthenticationKey isKindOfClass:[NSNull class]])) 
     [self showLoginViewAnimated:NO]; 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logoutHandler:) name:LOGOUT_NOTIFICATION object:self.view]; 

这里是我的登录处理在登录的ViewController实现(控制器A):

- (void)authenticateHandler:(NSNotification *)notification { 
    NSLog(@"[LoginViewController] Authenticate handler"); 

    NSDictionary *userDict = [notification userInfo]; 



    BOOL isUserAuthenticated = 
    //[username isEqualToString:[userDict objectForKey:@"username"]] && 
    //[password isEqualToString:[userDict objectForKey:@"password"]] && 
    [api_Key isEqualToString:[userDict objectForKey:@"apiKey"]] && 
    ([_auth isEqualToString:[userDict objectForKey:@"authKey"]]); 

    [[NSUserDefaults standardUserDefaults] setBool:isUserAuthenticated forKey:@"userLoggedIn"]; 
    [[NSUserDefaults standardUserDefaults] synchronize]; 

    if(isUserAuthenticated){ 

     NSLog(@"Authentificated"); 
     [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 

    } else { 
     NSLog(@"Not Authentificated"); 
     [self showAlert]; 
    } 
} 

而在一个loginView(视图控制器A)的viewDidLoad方法:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(authenticateHandler:) name:AUTHENTICATE_NOTIFICATION object:self]; 

如果你们能够给我一种模式或防呆在这怎么可能做到这将是巨大的理论。

因为此刻,我目前解雇与所示的MAINVIEW登录视图,但然后我呈现的tableview模态(动画),这是不desireable。所以你可以想象一个视图被动画解散,然后你看到主视图,然后通过动画在主视图上显示tableview。我不希望用户直到他们登录后才能看到主视图,并且他在选择游戏后查看详情,除非用户只有一个游戏!

还记得在视图A和C之间显示tableview的唯一原因是因为用户可能有超过1个游戏,但是如果他们只有1个游戏,则从控制器A到控制器C而不是控制器A到控制器B到控制器C.

回答

1

我不知道我完全理解这个问题,但这里的一些建议,我希望是有用的:

一个UINavigationController是特别适用于VCS的堆栈,尤其是,在我看来,在你出席的情况。

主要vc可以检查用户的登录状态,并提供登录vc或不。它可以通过假设用户有一个以上的游戏可供选择,打造VC堆栈如下开始:

- (void)viewDidAppear:(BOOL)animated { 

    // notice I moved the logical or to make the BOOL more meaningful 
    BOOL isUserLoggedIn = [[NSUserDefaults standardUserDefaults] boolForKey:@"userLoggedIn"] || (!setAuthenticationKey || [setAuthenticationKey isKindOfClass:[NSNull class]]); 

    if (!isUserLoggedIn) { 
     SelectGameVC *selectGameVC = // not sure how you build this, either alloc-init or get from storyboard 
     // notice animation==NO, we're putting this on the stack but not presenting it 
     [self.navigationController pushViewController:selectGameVC animated:NO]; 
     LoginVC *loginVC = // alloc or use UIStoryboard instantiateViewControllerWithIdentifier 
     // we push this one with animation, user will see it first 
     [self.navigationController pushViewController:loginVC animated:YES]; 
    } 
} 

当loginVC完成登录,也可以提出这样的问题,确实用户有一个以上的游戏吗?如果不止一个,只弹出一个vc来显示我们在下面堆叠的SelectGame vc,否则一路弹出。

// LoginVC.m 

// login successful 
if (loggedInUser.games.count > 1) { 
    // it's underneath us, remember? we pushed it before we got here 
    [self.navigationController popViewControllerAnimated:YES]; 
} else { 
    // it's underneath us, but we don't need it, pop all the way back 
    [self.navigationController popToRootViewControllerAnimated:YES]; 
} 

顺便说一句,你的NSLog让我微笑觉得我的老朋友谁常说“authentificated”,而不是“认证”的。

+0

这似乎是一种很好的实施方式。我明天将处理代码并给你一个更新。哈哈,是的,我有时不断地添加认证的单词,而不是使用经过验证的确切单词......我想这会让这个单词变得更加复杂,我更聪明,但实际上,更多的是无知的哈哈。 – jsetting32

+0

:-)我的好友常常说“验证”,它听起来像是“识别”,它是真实的。顺便说一句,如果你有一个用户类,你可以隐藏这个看起来很糟糕的isUserLoggedIn逻辑,用户名为 - (BOOL)isLoggedIn; – danh

+0

嘿@danh,所以我想问题是我没有使用导航堆栈,我只是有多个viewcontrollers在模态dimissed和呈现。有什么想法?也许这对我来说不可行?因为我不能实现弹出方法 – jsetting32

相关问题