ユーザーがログインした後ではなく、アプリの読み込み時にログイン画面を表示するために、ユーザーが正常にログインしたときにNSUserDefaultsに認証オブジェクトを追加することにしました。アプリが起動すると、そのauthパラメーターがチェックされ、それに応じてView Controllerが設定されます(ユーザーがauthの場合はフィードが表示され、そうでない場合はログイン画面が表示されます)後者の場合、アプリがありますユーザーがログインした後、デリゲートはルートビューコントローラーをフィードにリセットします。これは悪い習慣ですか、それともこれを行うためのより良い方法がありますか?
アプリデリゲート:
- (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];
}
}
}
それよりも良い方法や簡単な方法があるのだろうかと思います。ありがとうございました!
明確にするために。以前は問題なくUIWindowのrootViewControllerをリセットしていましたが、デバイスの回転を許可しているときにリセットしようとすると、いくつかの問題が発生しました—回転が機能しなくなっただけです。
デバッグしようとしたときに、Appleのドキュメントから直接次のことがわかりました。以下のリンクには、UIWindowの操作に関するいくつかのガイドラインがあります。これらはすべてデバイスの回転に関連していますが、それでも知っておくとよいでしょう。
簡単に言うと、ルートコントローラーを使用して、子ビューコントローラーを追加します。その後、問題なく子VCを交換できます。
•ビューコントローラのUIViewプロパティをサブビューとしてUIWindowに追加しました。
開発者は、ビューコントローラのviewプロパティをUIWindowのサブビューとして追加することをお勧めしません。アプリケーションのルートビューコントローラーは、Interface Builderで、または実行時にapplication:didFinishLaunchingWithOptions:から戻る前に、アプリウィンドウのrootViewControllerプロパティに割り当てる必要があります。複数のViewControllerからのコンテンツを同時に表示する必要がある場合は、独自のコンテナView Controllerを定義し、それをルートViewControllerとして使用する必要があります。カスタムコンテナビューコントローラの作成を参照してください。
詳細については、 この技術的なQ&A を確認してください。
window.rootViewController
をリセットすることは悪い習慣ではないと思います。ただし、ウィンドウを再作成する必要はありません。
以前のViewControllerを使用したくない場合は、ウィンドウのrootViewController
を新しいViewControllerに置き換えるだけです。以前のViewControllerに戻したい場合は、-presentViewController: animated: completion:
を使用してViewControllerを提示することをお勧めします。
ウィンドウを再度割り当てる必要はありません。これを直接設定できます。
window.rootViewController = yourVC;
ステップバイステップ私は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];
}
}