I'm searching for a solution to split Storyboard at UITabBar level.
I have an app with 5 tab and i want to manage every single tab with a different storyboard.
The structure would be a simple minimal storyboard with the tab bar controller and 5 bigger storyboards with every tab viewcontrollers (and segues) which must inherit the tab bar.
Does everyone ever splitted the storyboard like this ? Any clue?
Thanks
I think it could be possible, this should go in "viewDidLoad" of your custom UITabBarController...
NSMutableArray *controllersArray = [[NSMutableArray alloc] init];
// Load the initial UIViewController from every Storyboard
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Storyboard1" bundle:nil];
UIViewController *first = [sb instantiateViewControllerWithIdentifier:#"firstViewController"];
[controllersArray addObject:first];
// Repeat the process with the rest
...
// Set your controllers
self.viewControllers = [controllersArray copy];
Remember to set an Storyboard ID for every main UIViewController, in the example is 'firstViewController'.
we used RBStoryboardLink from: http://robsprogramknowledge.blogspot.co.il/search/label/UIStoryboard
to solve this issue
Related
We are working on splitting our main storyboard into smaller ones so that it makes source control merging easier. Any ideas on what the right approach is to load a new storyboard from a UITabBar?
Here's what we have so far in our custom subclassed UITabBarController:
UITabBarItem *cardsTabItem = [self.tabBar.items objectAtIndex:kTabBarIndexCards];
cardsTabItem.image = [[UIImage imageNamed:#"navCardsOff"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
cardsTabItem.selectedImage = [[UIImage imageNamed:#"navCardsOn"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
cardsTabItem.imageInsets = UIEdgeInsetsMake(-5, 0, 5, 0);
cardsTabItem.titlePositionAdjustment = UIOffsetMake(0, -5);
I've done the same thing before, but with a UITabBarController. In that case we had a storyboard for each of the tab buttons, even though one of the storyboards only had 1 view controller in it. I think wether you're using a UITabBarController or responding to the tab bar delegate the answer is the same. For each button clicked make the determination of which storyboard the view controller you want to load is in:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"leftButtonStoryboard" bundle:[NSBundle mainBundle]];
UIViewController *vc = [storyboard instantiateInitialViewController];
//or
UIStoryboard *otherVC = [storyboard instantiateViewControllerWithIdentifier:#"CameraViewController"];
Then you can present it, push it, or whatever.
In my case since I was using a UITabBarController this was all done during initialization of the controller for all the different buttons.
It will most likely come in handy to by default name all of the different view controller your using in your storyboard (the storyboard id), I usually name them after the viewController class so I don't have to remember what I called it.
I would also recommend that you avoid using the self.storyboard property when trying to instantiate another view controller because you might end up with a situation where a controller is shared between tabs. Being explicit with which storyboard you're loading a controller from can help with readability and avoidance of bugs.
Edit - a more concrete example:
What you need to do is set the viewControllers property of your UITabViewController, I do this in its init method. For example
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:[NSBundle mainBundle]];
UIViewController *one = [mainStoryboard instantiateViewControllerWithIdentifier:#"VC1"];
UIViewController *two = [mainStoryboard instantiateViewControllerWithIdentifier:#"VC2"];
self.viewControllers = #[one,two];
}
return self;
}
You can use this technique if your writing it in code itself or if you're using a storyboard. Beware that if you have other view controllers already hooked up via the storyboard you'll loose then unless you instantiate them there as well. You can also use the setViewControllers: animated: method as well.
The code for creating the custom tab bar items (the buttons at the bottom) should probably go within the individual view controllers and be assigned to its tabBarItem property. The UITabBarController will use that property to create the correctly styled button. If you don't provide the property you get the default buttons starting from 1.
I have created a .xib file containing a UITabBar with 5 UITabBarItems inside. I would like 4 of the 5 tabs to link to the same UIViewController class since they have the exact same interface (only the data differentiate their looks).
Therefore it makes sense for me to instantiate my UIViewController 4 times, once per tab bar item. And then link each one of the UITabBarItems of the .xib with one instance of my UIViewController.
But I cannot figure out a way to take a reference of my xib tab bar items in my UIViewController and send the setTabBarItem message. How could I achieve that ? I was trying somehow to pass the .xib tab bar items on init (overwriting the init) but I didn't manage to reference them. I instantiate the controllers in the AppDelegate after the self.window stuff.
(If I say something weird here, not making sense with the usual iOS programming conventions, please let me know)
Use UITabBarController for this , not sure what you exactly want to do with the same UIViewController but UITabbarController will definitely work;
UITabBarController *tabBarController = [[[UITabBarController alloc] init] autorelease];
ViewController *viewController1 = [[ViewController alloc]initWithNibName:#"ViewController1"];
ViewController2 *viewController2 = [[ViewController2 alloc]initWithNibName:#"ViewController2"];
tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1,viewController1,viewController1,viewController1,viewController2,nil];
self.window.rootViewController = tabBarController;
I've created a storyboard that has a UITabbarController all is working well but now I want to add some logic that determines which viewcontroller a particular tabbar button will display.
Example... if a customer has a valid subscription display viewcontroller one, if no subscription display viewcontroller two.
Is this possible using storyboards, I've looked at UITabBarDelegate and prepareForSegue but struggling to piece this together?
Are there any examples of how to do this sort of thing using StoryBoards?
Many thanks
You can set it like this:
if(hasSubscription)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
ViewController1* subsection = [storyboard instantiateViewControllerWithIdentifier:#"ViewController1"];
ViewController2* subsection1 = [storyboard instantiateViewControllerWithIdentifier:#"ViewController2"];
[(UITabBarController*)self.window.rootViewController setViewControllers:[NSArray arrayWithObjects:subsection,subsection1, nil]];
}
If you want to add rootviewController according to the subscription then above answer given by soryngod is good one.
But if you want to open viewControllers after rootviewcontroller loaded, then at tabBarButton press perform following code:-
before this code, add yours viewControllerONE and viewControllerTWO to the rootViewController by segues as shown: . And give each segue an identifier in AttributeInspector, example "one" for viewControllerONE and "two" for viewControllerTWO.
then at tabBarButton action do the following:-
if(subscription)
[self performSegueWithIdentifier:#"one" sender:self];
else
[self performSegueWithIdentifier:#"two" sender:self];
I have an UI Navigation project with tab bar, each tab bar is contain XIB and ViewController, the project is loaded each ViewController from the App delegate by this method :
MyFourthView *fourthViewController;
fourthViewController = [[MyFourthView alloc] initWithTabBar];
localNavigationController = [[UINavigationController alloc]
initWithRootViewController:fourthViewController];
[localControllersArray addObject:localNavigationController];
Now I am trying to add storyboard to my project, and load it from the app delegate programmatically to be a fifth tab bar view, but I don't know how I can do that? because there is no XiB in the storyBoard so the above method isn't work ?
If the fifth navigation controller you want to add to your tab bar is the root/initial viewcontroller in your storyboard you can instantiate it like this:
UINavigationController *fifthNavigationController = [[UIStoryboard storyboardWithName:#"yourstoryboardname" bundle:nil] instantiateInitialViewController];
If its not, give it a storyboard id and instantiate it like this:
UINavigationController *fifthNavigationController = [[UIStoryboard storyboardWithName:#"yourstoryboardname" bundle:nil] instantiateViewControllerWithIdentifier:#"storyboardIdOfYourNavController"];
Apple documents switching to using Storyboards here:
http://developer.apple.com/library/ios/#releasenotes/Miscellaneous/RN-AdoptingStoryboards/index.html
I need to make a set of decisions in the AppDelegate on launch - depending on the outcome of those decisions I need to go to specific parts of the storyboard.
So my question is - WITHOUT using any nav or tab controllers, how do I go to a specific part of a storyboard?
OR
Is the only supported option having multiple storyboards - for each of the 'outcomes' and then loading those as required?
Thanks
Give each ViewController a unique identifier in the storyboard.
Then in the appDelegate:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"PUT_UNIQUE_ID_HERE"];
//DO WHAT YOU WANT WITH YOUR VIEWCONTROLLER
//Example:Set it as the root view of the app window...
Give each of your ViewControllers a separate ID, and then instantiate the required one with:
UIViewController *initialVC = [storyboard instantiateViewControllerWithIdentifier:#"<identifier>"];