使用带有TabBarController的多个故事板 [英] Using multiple storyboards with a TabBarController

查看:87
本文介绍了使用带有TabBarController的多个故事板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,所以在开发我的最新应用程序的过程中,我发现我的故事板变得很大,所以为了清理它,我把它分开了进入多个故事板,然后失控。仅仅为了设置我有大约20 tableviewcontrollers 从根 NavigationController 分支出来。那个 navigationcontroller TabBarController 上的一个TabItem,它是应用程序的根视图控制器。

Okay, so in the process of developing my newest app, I found that my storyboard got huge, so in an effort to clean it up some, i have divided it into multiple storyboards before it gets out of hand. just for settings alone i have roughly 20 tableviewcontrollers that branch out from a root NavigationController. That navigationcontroller was a TabItem on a TabBarController, which is the application's root view controller.

我已将 TabBar 移动到它自己的 StoryBoard 作为 Root_Storyboard ,导航控制器现在是Settings_Storyboard的初始视图。

I've moved the TabBar into it's own StoryBoard as the Root_Storyboard and the Navigation controller is now the initial view of the Settings_Storyboard.

仅用于测试目的,我在 TabBarController (Root_Storyboard)中添加了一些 UIViewControllers 作为标签项,并将其子类化为一个,并将以下代码添加到其中 viewWillAppear 方法。它工作得很好,但我知道 presentViewController 以模态方式显示 NavigationController 并隐藏 tabBar 。显然我不想那样,我如何让它正确推送,以便 TabBar 仍然可见?

Just for testing purposes, I placed a few UIViewControllers as tab items in the TabBarController (Root_Storyboard) and subclassed one and added the following code to it's viewWillAppear method. It works great, but I know that the presentViewController displays the NavigationController modally and hides the tabBar. Obviously I don't want that, how do I get it to push properly so that the TabBar remains visible?

- (void) viewWillAppear:(BOOL)animated {
UIStoryboard *settingsStoryboard = [UIStoryboard storyboardWithName:@"Settings_iPhone" bundle:nil];
UIViewController *rootSettingsView = [settingsStoryboard instantiateInitialViewController];

[self.tabBarController presentViewController:rootSettingsView animated:NO completion:NULL];
}

编辑 - 澄清。上面的代码是Root_iPhone.storyboard中 UIViewController(UITabBarController的子代:index(1))的子类方法。我试图加载的 UINavigationController / UITableViewController 可以在 Settings_iPhone.storyboard 中找到。在这种情况下,不确定如何实现下面建议的linkView。

Edit - To clarify. The above code is the subclassed method for a UIViewController (child of UITabBarController:index(1)) in the Root_iPhone.storyboard. The UINavigationController/UITableViewController that I am trying to load is found in Settings_iPhone.storyboard. Not sure how to implement the linkView suggested below in this situation.

推荐答案

这很可能也是一个聪明的举动 - 整理你的故事板提供更清晰的界面文件,以便深入挖掘,减少XCode中的加载时间,以及更好的组编辑。

This is quite possible and a smart move - decluttering your Storyboards presents cleaner interface files to dig through, reduced loading times in XCode, and better group editing.

我已经在Stack Overflow上梳理了一段时间并注意到每个人都在求助自定义Segues或以编程方式实例化基于选项卡的设置。让人惊讶。我已经破解了一个简单的UIViewController子类,您可以将其用作故事板的占位符。

I've been combing across Stack Overflow for a while and noticed everyone is resorting to Custom Segues or instantiating tab based setups programmatically. Yikes. I've hacked together a simple UIViewController subclass that you can use as a placeholder for your storyboards.

代码:

头文件:

#import <UIKit/UIKit.h>

@interface TVStoryboardViewController : UIViewController

@end

实施文件:

#import "TVStoryboardViewController.h"



@interface TVStoryboardViewController()

@property (nonatomic, strong) UIViewController *storyboardViewController;

@end



@implementation TVStoryboardViewController



- (Class)class { return [self.storyboardViewController class]; }

- (UIViewController *)storyboardViewController
{
    if(_storyboardViewController == nil)
    {

        UIStoryboard *storyboard = nil;
        NSString *identifier = self.restorationIdentifier;

        if(identifier)
        {
            @try {
                storyboard = [UIStoryboard storyboardWithName:identifier bundle:nil];
            }
            @catch (NSException *exception) {
                NSLog(@"Exception (%@): Unable to load the Storyboard titled '%@'.", exception, identifier);
            }
        }

        _storyboardViewController = [storyboard instantiateInitialViewController];
    }

    return _storyboardViewController;
}

- (UINavigationItem *)navigationItem
{
    return self.storyboardViewController.navigationItem ?: [super navigationItem];
}

- (void)loadView
{
    [super loadView];

    if(self.storyboardViewController && self.navigationController)
    {
        NSInteger index = [self.navigationController.viewControllers indexOfObject:self];

        if(index != NSNotFound)
        {
            NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
            [viewControllers replaceObjectAtIndex:index withObject:self.storyboardViewController];
            [self.navigationController setViewControllers:viewControllers animated:NO];
        }
    }
}

- (UIView *)view { return self.storyboardViewController.view; }



@end

描述:


  1. 视图控制器使用其恢复标识符来实例化项目中的故事板。

  2. 一旦加载,它将尝试使用Storyboard的
    初始视图控制器在其
    UINavigationController的viewController数组中替换自身。

  3. 如果需要,此子类将返回Storyboard初始视图控制器的UINavigationItem。这是为了确保加载到UINavigationBars中的导航项在交换后对应于视图控制器。

用法:

要使用它,请将它指定为属于UINavigationController的Storyboard中的UIViewController的子类。

To use it, assign it as the subclass of a UIViewController in your Storyboard that belongs to a UINavigationController.

分配一个恢复身份证,你很高兴。

Assign it a Restoration ID, and you're good to go.

设置:

以下是您的看法在故事板中设置:

And here's how you set it up in the Storyboard:

此设置显示一个标签栏控制器,其中导航控制器作为其第一个标签控制器。每个导航控制器都有一个简单的UIViewController作为其根视图控制器(我已经将UIImageViews添加到占位符,以便于记住它链接到的内容)。它们中的每一个都是TVStoryboardViewController的子类。每个都有一个恢复ID设置到他们应该链接到的故事板。

This setup shows a tab bar controller with navigation controllers as its first tab controllers. Each navigation controller has a simple UIViewController as its root view controller (I've added UIImageViews to the placeholders to make it easy to remember what it links to). Each of them is a subclass of TVStoryboardViewController. Each has a Restoration ID set to the storyboard they should link to.

这里有些胜利:


  • 它似乎最适用于模式演示,其中子类是导航控制器的根视图控制器。

  • 子类不推堆栈上的任何控制器 - 它交换。这意味着您不必手动隐藏后退按钮或覆盖其他地方的标签行为。

  • 如果双击选项卡,它将带您进入Storyboard的初始视图,如预期(你不会再看到那个占位符了。)

  • 设置起来非常简单 - 没有自定义segues或设置多个子类。

  • 你可以添加UIImageViews以及你喜欢的任何占位符视图控制器,使你的故事板更清晰 - 它们永远不会显示。

  • It seems to work best for modal presentations where the subclass is the root view controller of a navigation controller.
  • The subclass doesn't push any controllers on the stack - it swaps. This means you don't have to manually hide a back button or override tab behaviour elsewhere.
  • If you double tap on a tab, it will take you to the Storyboard's initial view, as expected (you won't see that placeholder again).
  • Super simple to set up - no custom segues or setting multiple subclasses.
  • You can add UIImageViews and whatever you like to the placeholder view controllers to make your Storyboards clearer - they will never be shown.

一些限制:


  • 此子类需要属于链中某处的UINavigationController。

  • 此子类仅实例化Storyboard中的初始视图控制器。如果你想在链中进一步实例化一个视图控制器,你可以随时拆分你的故事板并重新应用这个子类技巧。

  • 这种方法在推送视图控制器时效果不佳。

  • 这种方法在用作嵌入式视图控制器时效果不佳。

  • 通过segue传递的消息可能无法正常工作。这种方法适用于界面部分是唯一的,不相关的部分(以模态或通过标签栏显示)的设置。

  • This subclass needs to belong to a UINavigationController somewhere in the chain.
  • This subclass will only instantiate the initial view controller in the Storyboard. If you want to instantiate a view controller further down the chain, you can always split your Storyboards further and reapply this subclass trick.
  • This approach doesn't work well when pushing view controllers.
  • This approach doesn't work well when used as an embedded view controller.
  • Message passing via segues likely won't work. This approach suits setups where sections of interface are unique, unrelated sections (presented modally or via tab bar).

这种方法被黑了要解决这个UITabBarController问题,请将其用作更大问题的部分解决方案。我希望Apple能够改进多故事板支持。但是对于UITabBarController设置,它应该是一种享受。

This approach was hacked up to solve this UITabBarController problem, so use it as a partial solution to a bigger issue. I hope Apple improves on 'multiple storyboard' support. For the UITabBarController setup however, it should work a treat.

这篇关于使用带有TabBarController的多个故事板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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