【问题标题】:Pushing views on the first run in UINavigationController在 UINavigationController 中第一次运行时推送视图
【发布时间】:2014-03-05 20:03:35
【问题描述】:

我在我的应用程序中实现了UINavigationController,我想要实现的是以编程方式确定该应用程序是否已启动。我需要这个来确定应该向用户显示哪个视图。如果这是第一次运行,我需要显示与其他任何时候不同的视图。

当我不使用 UINavigationController 时很容易,但在这种情况下,当我使用我的方法时,我将摆脱 UINavigationController 层次结构。

这是我用来确定首次运行的方法:

+ (void)executeBlockAtTheFirstRun:(void (^)())firstRunBlock atAnotherRun:(void (^)())anotherRunBlock
{
    // Checking whether HasAlreadyBeenLaunched key is set to be YES
    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HasAlreadyBeenLaunched"]) {
        // Running block given by the user when this isn't the first run of the app
        anotherRunBlock();

        // Uncomment this if you want the log
        //NSLog(@"Application has already been launched");
    } else {
        // Seeting the bool value for key HasAlreadyBeenLaunched and synchronising user defaults
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"HasAlreadyBeenLaunched"];
        [[NSUserDefaults standardUserDefaults] synchronize];

        // Running the block with code provided by the user for the first run of the app
        firstRunBlock();

        // Uncommeent this f you want the log
        // NSLog(@"This is the first run");
    }
}

所以当我放入完成块时:

NSString *storyboardID = [self hasEverBeenLaunched]? @"MainView" : @"LoginView";

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

并将所有内容放入 AppDelegate.m 我可以管理视图,但正如我所说,我的 UINavigationController 层次结构消失了。我应该怎么做才能让一切正常运行?

【问题讨论】:

    标签: ios iphone objective-c uiviewcontroller uinavigationcontroller


    【解决方案1】:

    如果您想要导航控制器,请制作导航控制器!而不是

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

    UIViewController* root =         
        [self.window.rootViewController.storyboard    
            instantiateViewControllerWithIdentifier:storyboardID];
    UINavigationController* nav = 
        [UINavigationController alloc] initWithRootViewController: root];
    self.window.rootViewController = nav;
    

    【讨论】:

    • 谢谢,这部分是我正在寻找的,但是有了这个解决方案,所有的层次结构都丢失了......我希望找到类似调用rootViewController的东西,并在其中确定第一次运行,如果有必要推到另一个视图只需将这个后退按钮设置为 root。
    【解决方案2】:

    storyboard 中直观地将您的根视图控制器设置为UINavigationController
    试试下面的方法:

    if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HasAlreadyBeenLaunched"]) {
    
    MainViewController *mainViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"MainViewController"];
    
        [self.navigationController setViewControllers:[NSArray arrayWithObject:mainViewController] animated:YES];
    
        } else {
    
    LoginViewController *loginViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"loginViewController"];
    
        [self.navigationController setViewControllers:[NSArray arrayWithObject:loginViewController] animated:YES];
    
        } 
    

    或者你可以像@matt 回答描述的那样直接设置你的根视图控制器。

    【讨论】:

      【解决方案3】:

      您必须先创建一个导航控制器并设置为根视图控制器:

      NSString *storyboardID = [self hasEverBeenLaunched]? @"MainView" : @"LoginView";
      UIViewController *vc = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:storyboardID];
      
      UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
      self.window.rootViewController = nc;
      [self.window makeKeyAndVisible];
      

      【讨论】:

        【解决方案4】:

        在情节提要中从 MainViewController segue 中创建名称为“ShowLoginView”的推送 LoginViewController。和代码:

        - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
        {
            if (!self.hasEverBeenLaunched) dispatch_async(dispatch_get_main_queue(), ^(){
               [[(UINavigationController*)self.window.rootViewController visibleViewController] performSegueWithIdentifier:@"ShowLoginView" sender:nil];
            });
            return YES;
        }
        

        【讨论】:

        • 这真的很棒!但是我得到“只有在源控制器由 UINavigationController 的实例管理时才能使用推送 segues”...奇怪,因为所有内容都嵌入在 UINavigationController
        • 使其成为模态转场而不是推送
        • @Cojoj,我编辑了 rootViewController UINavigatonController 的答案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-15
        • 1970-01-01
        • 2014-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多