简体   繁体   English

情节提要:更改情节提要中指定的UINavigation控制器的根视图

[英]Storyboard: Changing the Root View of a UINavigation Controller Specified in a Storyboard

I looked over the suggested list, and didn't see anything that seemed to fit my dilemma. 我查看了建议的列表,但没有发现任何适合我的困境的东西。

I am writing my first storyboard project. 我正在写我的第一个分镜脚本项目。 I have a UITabBarController that manages 4 tabs. 我有一个管理4个标签的UITabBarController。 Each tab has a UINavigationController as its root, and a number of views in each. 每个选项卡都有一个UINavigationController作为其根,并且每个选项卡中都有许多视图。

One of the navigation stacks is actually a "ring" of 3 view controllers. 导航堆栈之一实际上是3个视图控制器的“环”。 I use a custom segue to replace the usual "pile-on" of a navigation stack with a simple replacement (I pile one view on). 我使用自定义segue用一个简单的替换替换了导航堆栈中通常的“堆放”(我将一个视图放在上面)。

This works wonderfully. 这很棒。 The storyboard and custom segue are just what the doctor ordered. 情节提要和自定义脚本正是医生命令的。

However, I want to give the user the choice of which of the 3 views they start with (becomes the root of the navigation stack). 但是,我想让用户选择以它们开始的3个视图中的哪个(成为导航堆栈的根)。 The storyboard insists on my selecting one of them as the root, so I do. 情节提要坚持要我选择其中一个作为根,所以我这样做。 However, at runtime, the user may want the initial view to be different, so I want the navigation stack to have a different view. 但是,在运行时,用户可能希望初始视图不同,因此我希望导航堆栈具有不同的视图。

In a nib-based app, I'd simply instantiate a new controller from a nib, and replace the current root with that controller. 在基于笔尖的应用程序中,我只需从笔尖实例化一个新控制器,然后用该控制器替换当前根目录。

How do I pick out a controller and do that in a storyboard? 如何挑选一个控制器,并在情节提要中执行该操作?

UPDATE: Thanks to a comment in another thread , I was able to simplify this a bit. 更新: 感谢在另一个线程中的注释,我能够简化一点。

OK. 好。 I figured it out. 我想到了。

Instead of replacing the root, I simply push the appropriate controller on. 无需替换根,我只需将适当的控制器推入即可。 This is because changing the root requires re-instantiating the controller, and the fox just ain't worth the chase. 这是因为更改根目录需要重新实例化控制器,而狐狸不值得追逐。 This has zero effect on the UX, so we do it this way: 这对UX的影响为零,因此我们采用这种方式:

/**************************************************************//**
 \brief Selects the initial search screen, depending on the user's choice.
 *****************************************************************/
- (void)selectInitialSearchAndForce:(BOOL)force         ///< If YES, then the screen will be set to the default, even if we were already set to one.
{
    UITabBarController  *tabController = (UITabBarController *)self.window.rootViewController;

    [tabController setSelectedIndex:0]; // Set the tab bar to the search screens.

    if ( force )
        {
        UIStoryboard    *st = [tabController storyboard];

        [[searchNavController navigationController] popToRootViewControllerAnimated:NO];

        UIViewController    *newSearch = nil;

        switch ( [[BMLT_Prefs getBMLT_Prefs] searchTypePref] )
            {
            case _PREFER_MAP_SEARCH:
            if ([[UIDevice currentDevice] userInterfaceIdiom] != UIUserInterfaceIdiomPad)   // The map and simple searches are combined, on the iPad.
                {
                newSearch = [st instantiateViewControllerWithIdentifier:@"map-search"];
                }
            break;

            case _PREFER_ADVANCED_SEARCH:
            newSearch = [st instantiateViewControllerWithIdentifier:@"advanced-search"];
           break;
            }

        if ( newSearch )    // We push the controller, as opposed to changing the root, because it's easier, and doesn't violate any of our ground rules.
            {
            [[searchNavController navigationController] pushViewController:newSearch animated:NO];
            // In the case of the iPad, we use a standard navbar push, so we need to prime the simple view to properly populate the Advanced view back button.
            if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
                {
                UIViewController    *simpleViewController = [[[searchNavController navigationController] viewControllers] objectAtIndex:0];

                simpleViewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString([[simpleViewController navigationItem] title], nil)
                                                                                                         style:UIBarButtonItemStyleBordered
                                                                                                        target:nil
                                                                                                        action:nil];
                }
            }
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM