为了在应用加载时显示我的登录屏幕,而不是在用户登录后显示,我决定在用户成功登录时在NSUserDefaults中添加auth对象。当应用程序启动时,检查auth参数,并相应地设置视图控制器(如果用户是auth它将显示一个feed,如果没有它将显示一个登录屏幕)在后一种情况下,我有app委托在用户登录后将根视图控制器重置为源。这是不好的做法还是更好的方法?
在 app delegate :
中- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
IIViewDeckController* deckController = [self generateControllerStack];
self.rightController = deckController.rightController;
self.centerController = deckController.centerController;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if([[defaults objectForKey:@"auth"] isEqualToNumber:[NSNumber numberWithInt:1]]){
self.window.rootViewController = deckController;
}else{
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard"
bundle:nil];
UIViewController* vc = [sb instantiateViewControllerWithIdentifier:@"loginViewController"];
self.window.rootViewController = vc;
}
[self.window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:NO];
return YES;
}
- (void) setRoots
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
IIViewDeckController* deckController = [self generateControllerStack];
self.rightController = deckController.rightController;
self.centerController = deckController.centerController;
self.window.rootViewController = deckController;
[self.window makeKeyAndVisible];
}
在登录视图控制器:
中- (IBAction)loginClick:(id)sender {
if([_emailField.text length]>0&&[_passField.text length]>0){
NSString *user = _emailField.text;
NSString *pass = _passField.text;
[[API sharedInstance] login:user andPass:pass onCompletion:^(NSDictionary *json){
NSLog(@"%@", json);
if(![json objectForKey:@"error"]){
[API sharedInstance].authorized = 1;
NSNumber *auth = [NSNumber numberWithInt:1];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:auth forKey:@"auth"];
[defaults synchronize];
captureYouAppDelegate *app = [[UIApplication sharedApplication] delegate];
[app setRoots];
}else{
[API sharedInstance].authorized = 0;
}
}];
}else{
if([_emailField.text length]<1){
[_emailField becomeFirstResponder];
}else{
[_passField becomeFirstResponder];
}
}
}
我想知道是否有比这更好或更容易的方式。谢谢!
答案 0 :(得分:6)
只是澄清一下。我之前没有任何问题重置了UIWindow的rootViewController,但是当试图在允许设备轮换的同时尝试这样做时,我遇到了一些问题 - 旋转刚刚停止工作。
我在尝试调试时直接从Apple的文档中找到了以下内容。以下链接提供了许多有关使用UIWindow的指南。这些都与设备轮换有关,但仍然有待了解。
简短回答,使用根控制器并添加子视图控制器。然后,您可以毫无问题地换出子VC。
•您已将视图控制器的UIView属性添加到UIWindow作为子视图。
不鼓励开发人员将任何视图控制器的视图属性添加为UIWindow的子视图。应用程序的根视图控制器应该在Interface Builder中分配给应用程序窗口的rootViewController属性,或者在从应用程序返回之前在运行时分配:didFinishLaunchingWithOptions:。如果需要同时显示来自多个视图控制器的内容,则应定义自己的容器视图控制器并将其用作根视图控制器。请参阅创建自定义容器视图控制器。
查看this technical Q&A了解详情。
答案 1 :(得分:4)
我不认为重置window.rootViewController
是一种不好的做法。但是,无需重新创建窗口
如果您不想使用以前的视图控制器,只需将窗口的rootViewController
替换为新的视图控制器即可。如果您确实要切换回以前的视图控制器,请使用-presentViewController: animated: completion:
来显示视图控制器,这可能是更好的选择。
答案 2 :(得分:0)
无需再次分配窗口,您可以直接设置此
window.rootViewController = yourVC;
答案 3 :(得分:0)
Step by Step我在UINavigationController的帮助下展示了使用rootviewcontroller的良好实践
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.splash = [[SplashViewController alloc] initWithNibName: @"SplashViewController" bundle: nil];
self.window.rootViewController = self.splash;
[self.window makeKeyAndVisible];
DLog(@"finished initializing .....");
[self setRootViewController];
return YES;
}
- (void) setRootViewController
{
DLog(@"setRootViewController");
if (self.sessionManager.isLoggedIn)
{
[self navigateToHomeController];
} else {
[self navigateToLoginController];
}
}
- (void) navigateToHomeController
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"kStoryBoard" bundle: nil];
UINavigationController* homeNavigationController = [storyboard instantiateViewControllerWithIdentifier:@"kHomeNavController"];
NSArray* controllers = [homeNavigationController viewControllers];
if([controllers lastObject])
{
if ([[controllers objectAtIndex:0] isKindOfClass:[HomeViewController class]]) {
HomeViewController* homeController = (HomeViewController*) [controllers objectAtIndex:0];
self.window.rootViewController = [[OLNavigationViewController alloc] initWithRootViewController: homeController];
}
}
}
- (void) navigateToLoginController
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"kStoryBoard" bundle: nil];
UINavigationController* loginNavigationController = [storyboard instantiateViewControllerWithIdentifier:@"kLoginNavController"];
if ([loginNavigationController isKindOfClass:[OLLoginViewController class]]) {
OLLoginViewController* loginController = (OLLoginViewController*) loginNavigationController;
loginController.shouldHideToolBar = YES;
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController: loginController];
}
}