因此,我的应用程序逻辑存在问题,即根据用户的凭据,我的应用程序的主视图是否应在登录 View 被关闭后在主视图上显示表格 View ,或者仅显示主视图登录 View 被关闭后的 View 。
因此,目前,我向服务器发送一个 http post 请求,在其中获取 token ,然后再进行一次调用以获取用户拥有的列表项数量,比如说游戏。
如果用户只有一款游戏,我希望显示主视图,但如果用户有多个游戏,那么用户应该看到一个表格 View ,按下其中一个单元格,然后以模态方式关闭表格 View 以显示主视图。
通常我有这 3 个 Controller ,至少这是我思考应该如何实现的方式,不确定它是否是正确的方式。
所以假设 Controller A是登录, Controller B是 TableView , Controller C是主视图。
Controller C 位于堆栈底部,而 Controller A 位于顶部。但 Controller B 可能会或可能不会根据 Controller A 的信息显示。当我说堆栈底部时,我的意思是如果用户尚未登录,则将显示登录 View ( Controller A)主视图上没有动画( Controller C)。因此,从技术上讲,主视图( Controller C)始终会加载,但只有在通过正确提交的凭据关闭登录 View 之后,数据才提供给它。
这里有一些在 mainviewcontroller( Controller C)中实现的方法,用于检查用户是否已登录,如果没有,那么应用程序在技术上首先会通过 mainviewcontroller,然后显示登录 View 。我知道这是应用程序开发登录模式的方法,但我不是 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];
}
在主视图(viewcontroller C)的viewdidLoad中:
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];
这是我在登录 View Controller ( Controller 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];
}
}
并在登录 View ( View Controller A)的viewDidLoad方法中:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(authenticateHandler:) name:AUTHENTICATE_NOTIFICATION object:self];
如果你们能给我一种模式或万无一失的理论来说明如何做到这一点,那就太好了。
因为目前,我当前关闭了显示主视图的登录 View ,但随后我以模态方式(动画)呈现了表格 View ,这是不可取的。因此,您可以想象一个 View 通过动画被消除,然后您会看到主视图一秒钟,然后 TableView 通过动画呈现在主视图上。我不希望用户在登录之前看到主视图,并且在选择一个游戏来查看详细信息之后,除非用户只有一个游戏!
请记住, TableView 显示在 View A 和 C 之间的唯一原因是因为用户可能有超过 1 个游戏,但如果他们只有 1 个游戏,则从 Controller A 转到 Controller C,而不是 Controller A到 Controller B 到 Controller C。
最佳答案
我不确定我是否完全理解这个问题,但这里有一些我希望有用的建议:
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 让我想起我的老 friend ,他过去常说“已验证”而不是“已验证”。
关于iphone - View Controller 堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17736100/