如何使用情节提要ID显示各种视图控制器(每个都有各自的导航控制器) [英] how to display various view controllers (each having its respective navigation controller) using storyboard ID

查看:83
本文介绍了如何使用情节提要ID显示各种视图控制器(每个都有各自的导航控制器)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发我的第一个应用程序.这是我要完成的事情:

I'm working on my first app. Here's what I want to accomplish:

将有一个包含几个不同选项的菜单.为简单起见,假定它由具有IBAction插座的UIButton组成,并且存在可以随时拉出菜单的功能.

There will be a menu with several different options. For simplicity, assume this is comprised of UIButtons with IBAction outlets and the functionality exists to pull up the menu at any time.

每个菜单按钮在按下时应显示不同的导航控制器内容.如果用户调出菜单并做出其他选择,则不应影响他当前正在操作的导航控制器;新选择的导航链将显示在旧导航链的顶部,并且通过菜单,用户可以随时返回到上一个导航链所保留的视图.

Each menu button, when pressed, should display a different navigation controller's content. If the user brings up the menu and makes a different selection, the navigation controller in which he is currently operating should not be affected; the newly selected navigation chain is displayed on top of the old, and through the menu, the user can go back to the view where he left off on the previous navigation chain at any time.

视觉插图(单击可获得更高的分辨率):

visual illustration (click for higher resolution):

请注意,有3种不同的导航控制器/链条.根视图控制器(在此简化版本中也是菜单)不属于任何一个.如果先前已经实例化了导航链之一,将无法重新实例化,这是为什么:如果用户在选项2的屏幕3上,然后从菜单中选择选项1,然后从菜单中再次选择选项2,在菜单上,他应该查看选项2-右的屏幕3(在该屏幕上,他停止了操作);他先前离开导航链时正在查看的视图控制器应该带回到顶部.

Please note that there are 3 different navigation controllers/chains. The root view controller (which is also the menu in this simplified version) is not part of any of them. It will not suffice to instantiate one of the navigation chains anew when it has been previously instantiated, and here's why: if the user was on screen 3 of option 2 and then selects option 1 from the menu and then selects option 2 (again) from the menu, he should be looking at screen 3 of option 2--right where he left off; the view controller he was viewing when he previously left the navigation chain should be brought back to the top.

如果没有导航控制器,我可以使按钮实例化并从情节提要中显示视图控制器:

I can make a button instantiate and present a view controller from the storyboard if there is NOT a navigation controller:

- (IBAction)buttonPressed:(id)sender {
    UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"View 2"];
    [self presentViewController:controller animated:YES completion:nil];
}

但是,我不知道如何使这两种方法与所涉及的导航控制器一起工作.而且,我不确定这两种方法是正确的选择,因为我并不总是想实例化一个新的视图控制器:当按下菜单按钮时,应该执行检查以查看视图是否显示(导航?)具有相应标识符的控制器已被实例化.如果是这样,应该将其简单地设置为顶视图控制器.

However, I can't figure out how to make those two methods work with a navigation controller involved. Moreover, I'm not sure those two methods are the right choice, because I won't always want to instantiate a new view controller: when a menu button is pressed, a check should be performed to see if the view (navigation?) controller with the corresponding identifier has already been instantiated. If so, it should simply be made the top view controller.

总而言之,这是我的问题:

In summary, here are my questions:

1)我应该如何实例化和显示嵌入在导航控制器中的视图控制器,最好使用情节提要ID?您是否使用导航控制器或视图控制器的情节提要ID?

1) How should I instantiate and display a view controller that is embedded in a navigation controller, preferably using a storyboard ID? Do you use the storyboard ID of the navigation controller or of the view controller?

2)如何检查实例是否已存在?同样,我应该检查现存的导航控制器还是视图控制器,这样做的最佳方法是什么?

2) How should I check whether an instance already exists? Again, should I check for an extant navigation controller or for a view controller, and what's the best method to do so?

3)如果所选的导航链已被实例化并且位于视图控制器堆栈中的某个位置,那么将其置于顶部的最佳方法是什么?

3) If the selected navigation chain has already been instantiated and is in the stack of view controllers somewhere, what is the best method for bringing it to the top?

谢谢!

旁注-很高兴知道如何粘贴保留缩进和颜色格式的代码片段:)

side note -- it would be nice to know how to paste code snippets with indentation and color formatting preserved :)

推荐答案

正如罗伯(Rob)所建议的那样,选项卡栏控制器将为您的设计提供良好的组织原则.

As Rob has suggested, a tab bar controller would make a good organising principle for your design.

在您的情节提要中添加一个UITabBarController,为其提供一个情节提要iD.将三组viewController中的每组(及其各自的navController)分配给tabBarController中的选项卡项.

Add a UITabBarController to your storyboard, give it a storyboard iD. Assign each of your three sets of viewControllers ( with their respective navController) to a tab item in the tabBarController.

 UITabBarController
      |--> UINavigationController --> VC1  ---> VC2  -->
      |--> UINavigationController --> VC1  ---> VC2  -->
      |--> UINavigationController --> VC1  ---> VC2  -->

在您的应用程序委托中,建立一个强大的属性来保存选项卡栏控制器的指针.当标签栏控制器保持指向所有标签项的指针时,这将照顾每个viewController组的状态.您不必为每个指针保留单独的指针,并且可以通过tabBarController的viewControllers属性获取对它们的引用.

In you app delegate make a strong property to hold your tab bar controller's pointer. As the tab bar controller keeps pointers to all of it's tab items, this will take care of state for each of your sets of viewControllers. You won't have to keep separate pointers for any of them, and you can get references to them via the tabBarController's viewControllers property.

@property (strong, nonatomic) UITabBarController* tabVC;

在启动时将其初始化

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard storyBoard = 
        [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];

self.tabVC = [storyBoard instantiateViewControllerWithIdentifier:@"tabVC"];

    //hide the tab bar 
for (UINavigationController* navController in self.tabVC.viewControllers)
    [navController.viewControllers[0] setHidesBottomBarWhenPushed:YES];

    return YES;
}

隐藏标签栏的另一种方法是为每个(初始)viewController选中Attributes Inspector中的"Push时隐藏底部栏"框.您不必为后续的viewController执行此操作,只需在该选项卡项中看到第一个即可.

An alternative way to hide the tab bar is to check the "Hides bottom bar on push" box in the Attributes Inspector for each of the (initial) viewControllers. You don't have to do this for subsequent viewControllers, just the first one that will be seen in that tab item.

然后,当您需要导航到navController组之一时...

Then when you need to navigate to one of your navController groups…

- (IBAction)openTab:(UIButton*)sender {

    AppDelegate* appDelegate = 
            (AppDelegate*)[[UIApplication sharedApplication] delegate];

    if ([sender.titleLabel.text isEqualToString: @"Option 1"]) {
        appDelegate.tabVC.selectedIndex = 0;
    }else if ([sender.titleLabel.text isEqualToString: @"Option 2"]){
        appDelegate.tabVC.selectedIndex = 1;
    }else if ([sender.titleLabel.text isEqualToString: @"Option 3"]){
        appDelegate.tabVC.selectedIndex = 2;
    }
    [self presentViewController:appDelegate.tabVC
                       animated:YES completion:nil];
}

(此示例使用presentViewController,您的应用程序设计可能会以其他方式浏览…)

(this example uses presentViewController, your app design may navigate this in other ways…)

更新

如果要在不使用标签栏控制器的情况下执行此操作,则可以实例化一个包含指向每个导航控制器的指针的数组:

If you want to do this without a tab bar controller, you can instantiate an array holding pointers to each of your nav controllers instead:

UINavigationController* ncA =
    [storyboard instantiateViewControllerWithIdentifier:@"NCA"];
UINavigationController* ncB =
    [storyboard instantiateViewControllerWithIdentifier:@"NCB"];
UINavigationController* ncC =
    [storyboard instantiateViewControllerWithIdentifier:@"NCC"];

self.ncArray = @[ncA,ncB,ncC];

哪个优点是没有标签栏可以隐藏...

Which has the benefit of not having a tab bar to hide…

然后您的选择看起来像…

Then your selection looks like…

- (IBAction)openNav:(UIButton*)sender {

    AppDelegate* appDelegate = 
           (AppDelegate*)[[UIApplication sharedApplication] delegate];
    int idx = 0;
    if ([sender.titleLabel.text isEqualToString: @"option 1"]) {
        idx = 0;
    }else if ([sender.titleLabel.text isEqualToString: @"option 2"]){
        idx = 1;
    }else if ([sender.titleLabel.text isEqualToString: @"option 3"]){
        idx = 2;
    }
    [self presentViewController:appDelegate.ncArray[idx]
                       animated:YES completion:nil];
}

这篇关于如何使用情节提要ID显示各种视图控制器(每个都有各自的导航控制器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆