在didFinishLaunching上自定义视图控制器堆栈

时间:2015-02-20 22:35:05

标签: ios uiviewcontroller uikit

我正在尝试使用以下代码在首次启动时为我的应用程序提供教程/登录/简介视图控制器:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    UIViewController *firstController = [[UIViewController alloc] init];
    [self.window setRootViewController:firstController];

    if ([self shouldShowIntro]) {
        IntroViewController *introViewController = [[IntroViewController alloc] init];
        [firstController presentViewController:introViewController animated:NO completion:nil];
    }

    return YES;
}

这很好用,但是会发生令人讨厌的视觉效果......在看到IntroViewController之前,有firstController可见的瞬间。我尝试在设置窗口的rootViewController之前显示IntroViewController,但这(不足为奇)会导致以下警告:

Warning: Attempt to present <IntroViewController: 0x7fd8eb3362f0> on <UIViewController: 0x7fd8eb335180> whose view is not in the window hierarchy!

如果没有这种令人烦恼的视觉闪光,我怎么能以模态方式呈现IntroViewController?我希望IntroViewController在启动屏幕消失后已经显示,并且能够以模态方式解除。

3 个答案:

答案 0 :(得分:0)

以下适合我,在iPhone 6和模拟器上的iOS 8.1上没有闪烁运行。我使用SDK版本8.1,我认为你的SDK级别不同,因为我得到的警告和结果与你使用提供的代码不同。

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

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    UIViewController *firstController = [[UIViewController alloc] init];
    firstController.view.backgroundColor = [UIColor blueColor];
    [self.window setRootViewController:firstController];

    dispatch_async(dispatch_get_main_queue(), ^{
        UIViewController* modalViewController = [[UIViewController alloc] init];
        modalViewController.view.backgroundColor = [UIColor grayColor];
        [firstController presentViewController: modalViewController animated: NO completion: nil];
    });

    // dismiss after a few seconds..
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [firstController dismissViewControllerAnimated: YES completion: nil];
    });

    return YES;
}
使用MMDrawerController

更新

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

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    MMDrawerController *drawerController = [[MMDrawerController alloc] init];
    drawerController.centerViewController = [[UIViewController alloc] init];
    drawerController.centerViewController.view.backgroundColor = [UIColor blueColor];
    drawerController.rightDrawerViewController = [[UIViewController alloc] init];
    drawerController.rightDrawerViewController.view.backgroundColor = [UIColor greenColor];
    drawerController.openDrawerGestureModeMask = MMOpenDrawerGestureModeAll;
    drawerController.closeDrawerGestureModeMask = MMOpenDrawerGestureModeAll;

    [self.window setRootViewController:drawerController];

    dispatch_async(dispatch_get_main_queue(), ^{
        UIViewController* modalViewController = [[UIViewController alloc] init];
        modalViewController.view.backgroundColor = [UIColor grayColor];
        [drawerController presentViewController: modalViewController animated: NO completion: nil];
    });

    // dismiss after a few seconds..
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [drawerController dismissViewControllerAnimated: YES completion: nil];
    });

    return YES;
}

此外,根据您的评论,它听起来好像预先加载的视图是关键。在出现之前尝试调用[firstController视图]和[modalController视图]以确保它们已被加载。

答案 1 :(得分:0)

尝试将此行移到设置视图控制器的代码下方。

[self.window makeKeyAndVisible];

类似的东西:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];

    UIViewController *firstController = [[UIViewController alloc] init];
    [self.window setRootViewController:firstController];

    if ([self shouldShowIntro]) {
        IntroViewController *introViewController = [[IntroViewController alloc] init];
        [firstController presentViewController:introViewController animated:NO completion:nil];
    }

    [self.window makeKeyAndVisible];

    return YES
}

答案 2 :(得分:0)

if ([self shouldShowIntro]) {
    IntroViewController *introViewController = [[IntroViewController alloc] init];
    [firstController presentViewController:introViewController animated:NO completion:nil];
}

到FirstViewController的viewDidAppear函数而不是在AppDelegate中。这应该抑制警告并顺利执行操作。