为了账号安全,请及时绑定邮箱和手机立即绑定

有条件地从AppDelegate的情节提要中的不同位置开始

有条件地从AppDelegate的情节提要中的不同位置开始

明月笑刀无情 2019-12-09 14:11:19
我有一个故事板设置了正常的登录名和主视图控制器,主视图控制器是登录成功后用户导航到的视图控制器。我的目标是如果身份验证(存储在钥匙串中)成功,则立即显示主视图控制器,如果身份验证失败,则显示登录视图控制器。基本上,我想在AppDelegate中执行以下操作:// url request & response work fine, assume success is a BOOL here// that indicates whether login was successful or notif (success) {          // 'push' main view controller} else {          // 'push' login view controller}我知道方法performSegueWithIdentifier:但是该方法是UIViewController的实例方法,因此无法从AppDelegate中调用。如何使用现有的情节提要板来完成此任务?编辑:情节提要的初始视图控制器现在是导航控制器,没有连接任何东西。我使用了setRootViewController:区别,因为MainIdentifier是UITabBarController。这就是我的代码:- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{            BOOL isLoggedIn = ...;    // got from server response    NSString *segueId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];    UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:segueId];    if (isLoggedIn) {        [self.window setRootViewController:initViewController];    } else {        [(UINavigationController *)self.window.rootViewController pushViewController:initViewController animated:NO];    }    return YES;}欢迎提出建议/改进!
查看完整描述

3 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

我假设您的情节提要板被设置为“主情节提要板”(UIMainStoryboardFileInfo.plist中的键)。在这种情况下,UIKit将加载情节提要,并将其初始视图控制器设置为窗口的根视图控制器,然后再发送application:didFinishLaunchingWithOptions:到AppDelegate。


我还假设情节提要中的初始视图控制器是导航控制器,您要将主视图或登录视图控制器推入该导航控制器。


您可以向窗口询问其根视图控制器,并将performSegueWithIdentifier:sender:消息发送给它:


NSString *segueId = success ? @"pushMain" : @"pushLogin";

[self.window.rootViewController performSegueWithIdentifier:segueId sender:self];


查看完整回答
反对 回复 2019-12-09
?
绝地无双

TA贡献1946条经验 获得超4个赞

我对这里提出的一些解决方案感到惊讶。


故事板中实际上不需要虚拟的导航控制器,无需在viewDidAppear:或任何其他黑客上隐藏视图并触发segues。


如果没有在plist文件中配置情节提要,则必须自己创建窗口和根视图控制器:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{        

    BOOL isLoggedIn = ...;    // from your server response


    NSString *storyboardId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];

    UIViewController *initViewController = [storyboard instantiateViewControllerWithIdentifier:storyboardId];


    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    self.window.rootViewController = initViewController;

    [self.window makeKeyAndVisible];


    return YES;

}

如果在应用程序的plist中配置了故事板,则在调用application:didFinishLaunching:时将已经设置了窗口和根视图控制器,并且将在窗口上为您调用makeKeyAndVisible。


在这种情况下,它甚至更简单:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{        

    BOOL isLoggedIn = ...;    // from your server response


    NSString *storyboardId = isLoggedIn ? @"MainIdentifier" : @"LoginIdentifier";

    self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:storyboardId];


    return YES;

}


查看完整回答
反对 回复 2019-12-09
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

如果您的情节提要的入口点不是UINavigationController:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {



    //Your View Controller Identifiers defined in Interface Builder

    NSString *firstViewControllerIdentifier  = @"LoginViewController";

    NSString *secondViewControllerIdentifier = @"MainMenuViewController";


    //check if the key exists and its value

    BOOL appHasLaunchedOnce = [[NSUserDefaults standardUserDefaults] boolForKey:@"appHasLaunchedOnce"];


    //if the key doesn't exist or its value is NO

    if (!appHasLaunchedOnce) {

        //set its value to YES

        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"appHasLaunchedOnce"];

        [[NSUserDefaults standardUserDefaults] synchronize];

    }


    //check which view controller identifier should be used

    NSString *viewControllerIdentifier = appHasLaunchedOnce ? secondViewControllerIdentifier : firstViewControllerIdentifier;


    //IF THE STORYBOARD EXISTS IN YOUR INFO.PLIST FILE AND YOU USE A SINGLE STORYBOARD

    UIStoryboard *storyboard = self.window.rootViewController.storyboard;


    //IF THE STORYBOARD DOESN'T EXIST IN YOUR INFO.PLIST FILE OR IF YOU USE MULTIPLE STORYBOARDS

    //UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"YOUR_STORYBOARD_FILE_NAME" bundle:nil];


    //instantiate the view controller

    UIViewController *presentedViewController = [storyboard instantiateViewControllerWithIdentifier:viewControllerIdentifier];


    //IF YOU DON'T USE A NAVIGATION CONTROLLER:

    [self.window setRootViewController:presentedViewController];


    return YES;

}

如果您的情节提要的入口点是UINavigationController替换项:


//IF YOU DON'T USE A NAVIGATION CONTROLLER:

[self.window setRootViewController:presentedViewController];

与:


//IF YOU USE A NAVIGATION CONTROLLER AS THE ENTRY POINT IN YOUR STORYBOARD:

UINavigationController *navController = (UINavigationController *)self.window.rootViewController;

[navController pushViewController:presentedViewController animated:NO];


查看完整回答
反对 回复 2019-12-09
  • 3 回答
  • 0 关注
  • 526 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信