Using Multiple Storyboards Using TabBarController

Ok, so in the process of developing my new application, I found that my storyboard became huge, so to clear it, I divided it into multiple storyboards before it got out of hand. for settings only, I have about 20 tableviewcontrollers that go out of the root of the NavigationController . This NavigationController was a TabItem on the TabBarController , which is the application's root view controller.

I moved the TabBar to my own storyboard as Root_Storyboard , and the navigation controller is now the initial view of the Settings_Storyboard.

Just for testing, I put several UIViewControllers as tabs in the TabBarController (Root_Storyboard) and subclassed one and added the following viewWillAppear code to it. It works fine, but I know that presentViewController displays the NavigationController modulo and hides the TabBar . Obviously, I don't want this, how do I get it to click correctly 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]; } 

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

+8
ios objective-c iphone storyboard uitabbarcontroller
source share
4 answers

It’s quite possible, and a smart move - advertising your storyboards is cleaner interface files for scrolling, reducing loading time in Xcode and improving group editing.

I combed Qaru for a while and noticed that everyone was resorting to Custom Segues program settings or creating tab-based instances. Clap. I hacked into a simple subclass of UIViewController that you can use as a placeholder for your storyboards.

The code:

Header file:

 #import <UIKit/UIKit.h> @interface TVStoryboardViewController : UIViewController @end 

Implementation File:

 #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 

Description:

  • The view controller uses its Recovery ID to create storyboards in your project.
  • After loading, it will try to replace itself with its UINavigationController viewController array with the layout of the initial view controller.
  • Upon request, this subclass returns the UINavigationItem of the Storyboard's initial view controller. This is necessary so that the navigation elements loaded in the UINavigationBars correspond to the view controllers after the exchange.

Application:

To use it, assign it as a subclass of UIViewController in your storyboard owned by UINavigationController.

enter image description here

Give it a recovery identifier, and you're good to go.

enter image description here

Setup:

And here is how you set it up in the Storyboard:

Diagram showing setup

This setting shows the tab bar controller with the navigation controllers as its first tab controllers. Each navigation controller has a simple UIViewController as its root view controller (I added UIImageViews to placeholders to make it easy to remember what it's attached to). Each of them is a subclass of TVStoryboardViewController. Each of them has a recovery identifier set for the storyboard to which they must refer.

Some win here:

  • It seems to be best suited for modal presentations, where the subclass is the root view controller of the navigation controller.
  • The subclass does not push any controllers on the stack - it swaps. This means that you don’t need to manually hide the back button or redefine the tab elsewhere.
  • If you double-tap the tab, it will bring you back to the original type of storyboard, as expected (you will no longer see this placeholder).
  • Super easy to configure - no user settings or setting multiple subclasses.
  • You can add UIImageViews and whatever you like to widget controllers to make your storyboards more readable - they will never be shown.

Some limitations:

  • This subclass must belong to the UINavigationController somewhere in the chain.
  • This subclass will instantiate the source view controller in the storyboard. If you want to create an instance of the view controller down the chain, you can always split your storyboards and reapply this subclass trick.
  • This approach does not work when you click on view controllers.
  • This approach does not work when used as a built-in view controller.
  • Messaging through segues probably won't work. This approach approaches settings where interface sections are unique, unrelated sections (presented both in models and through the tab bar).

This approach has been hacked to solve this UITabBarController problem, so use it as a partial solution to a larger problem. Hopefully Apple will improve in supporting multiple storyboards. However, to configure the UITabBarController, this should work.

+10
source share

Not sure if your question has been answered, and for others who are looking for a solution to this problem, try this method.

enter image description here

  • Create a tab bar controller with navigation controllers in a single storyboard file. And add an empty view controller (I called it RedirectViewController) as shown in the picture.
  • The child view controller (let it set the SettingsViewController for your case) is located in Settings_iPhone.storyboard.
  • In RedirectViewController.m enter the code:

     - (void)viewWillAppear:(BOOL)animated { UIStoryboard *settingsStoryboard = [UIStoryboard storyboardWithName:@"Settings_iPhone" bundle:nil]; UIViewController *rootSettingsView = [settingsStoryboard instantiateInitialViewController]; [self.navigationController pushViewController:rootSettingsView animated:NO completion:nil]; } 
  • SettingsViewController will be displayed immediately when the Settings tab is clicked.
  • The decision is not yet complete! You will see "<Back" as the left navigation item in SettingsViewController. Use the following line in the viewDidLoad method:

     self.navigationItem.hidesBackButton = YES; 
  • In addition, in order not to delete the same element of the tab bar and cause a transition back to the empty rootViewController, target view controllers must implement UITabBarControllerDelegate

     - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { return viewController != tabBarController.selectedViewController; } 

This works for me.

+5
source share

It's a little late for the Hawke_Pilot, but it may help others.

Starting with iOS 9.0, you can create a relationship binding to another storyboard. This means that the barcode view controllers can refer to View Controllers on another storyboard without any tricks that can be found in other answers here. :-)

However, this alone does not help, because the recipient in another storyboard does not know that he is connected to the tab bar view controller and does not display the tab bar for editing. All you need to do when you point the Storyboard link to the desired view controller, select the Storyboard link and select Editor-> Paste In-> Navigation Controller. This means that the Nav Controller knows that it is connected to the tab bar view controller because it is on the same storyboard and displays the tab bar at the bottom and allows you to edit the image and button title. No code required.

Admittedly, this may not suit everyone, but may work for the OP.

+5
source share

Add the following code to your LinkViewController

 -(void) awakeFromNib{ [super awakeFromNib]; ///…your custom code here .. UIStoryboard * storyboard = [UIStoryboard storyboardWithName:self.storyBoardName bundle:nil]; UIViewController * scene = nil; // Creates the linked scene. if ([self.sceneIdentifier length] == 0) scene = [storyboard instantiateInitialViewController]; else scene = [storyboard instantiateViewControllerWithIdentifier:self.sceneIdentifier]; if (self.tabBarController) scene.tabBarItem = self.tabBarItem; } 

Here is the screen image for LinkViewController Screen shot .

LinkViewController is simply the placeholder where the new viewController will be hosted. Here is an example of the code that I used for my application.

RBStoryboardLink . It works great for me. Let me know if this helps you.

+2
source share

All Articles