I have made a custom UITabBar that is working very well, but I introduced a change to navigation and now i am having some serious issues. Here is what I have:
General Setup
TabBarController
NavbarController1 - TabBarItem1
Links to: PeopleView
NavbarController2 - TabBarItem2
Links to: ContentView
NavbarController3 - TabBarItem3
Links to: ContentView //Same VC as TabBaritem 2.
App Delegate - In my didFinishLaunchingWithOptions method I call a customizeTabBar method as follows
-(void) customizeTabBar
{
UITabBarController *tabVC = (UITabBarController *) self.window.rootViewController;
//Load Navigation Bar images
NSArray *unSelectedImages = [[NSArray alloc] initWithObjects:@"image1.jpg", @"image2.jpg", @"image3.jpg", @"image4.jpg", @"image5.jpg", nil];
NSArray *selectedImages = [[NSArray alloc] initWithObjects:@"image1_on.jpg", @"image2_on.jpg", @"image3_on.jpg", @"image4_on.jpg", @"image5_on.jpg", nil];
NSArray *items = tabVC.tabBar.items;
for (int idx = 0; idx < items.count; idx++)
{
UITabBarItem *barItem = [items objectAtIndex:idx];
barItem.tag = idx;
UIImage *selectedImage = [UIImage imageNamed:[selectedImages objectAtIndex:idx]];
UIImage *unSelectedImage = [UIImage imageNamed:[unSelectedImages objectAtIndex:idx]];
UIEdgeInsets inset = {
.top = 10,
.left = 0,
.bottom = -10,
.right = 0
};
barItem.imageInsets = inset;
[barItem setFinishedSelectedImage:selectedImage withFinishedUnselectedImage:unSelectedImage];
}
So far this is working beautifully.
Here is where the problem comes in. In order to get my TabBarItem3 to link to ContentView, I implemented the following code in my TabBarClass:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
if (viewController.tabBarItem.tag == 1 || viewController.tabBarItem.tag == 2 )
{
// Validating if is necesarry to replace the TabBarController.ViewControllers
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
MediaList *mediaView = [storyboard instantiateViewControllerWithIdentifier:@"SB_MediaList"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mediaView];
NSMutableArray *viewsArray = [NSMutableArray arrayWithArray:self.viewControllers];
if (viewController.tabBarItem.tag == 1)
{
//Setting the specfic data for my instance for tabBarItem 1
NSLog(@"Here we are in 1");
[mediaView setContent:@"Personalized content/data for TabBarItem 1"];
}
else if (viewController.tabBarItem.tag == 2)
{
//Setting the specfic data for my instance for tabBarItem 2
NSLog(@"Here we are in 2");
[mediaView setContent:@"Personalized content/data for TabBarItem 2"];
}
[viewsArray replaceObjectAtIndex:viewController.tabBarItem.tag withObject:navigationController];
self.viewControllers = viewsArray;
}
}
Upon execution of this code, I lose the images associated with my custom tab bar for items 2 or 3 (depending on which I select).
UPDATE
So, I moved my tab bar customization method out of my delegate and into a maintabbar class and I call it on viewdidload and I the meh hid didselectviewcontroller. This seems to solve the problem with missing images, but has created a bad side effect of flickering on the screen when I click either of hose items. I have tried different combinations of removing it from the viewdidload method as we'll, but still no luck..
As I understand the purpose of this whole thing is to avoid having to create different classes for two tab bar items that will perform almost the same thing but with different data.
So fist, you have to defined a class capable of doing such thing, let's call it
CommonClass
. This class will have to have the necessary methods for doing a properly initialization. [I'm sure you have done this].Then on your storyboard, you will still need to have two
ViewController
elements, each one as rootViewController of it's correspondingNavigationController
.I strongly recommend doing this way instead of trying to assign a new instance by code as we tried on: Linking to a view multiple times from tabar. Those two view controllers obviously belong to the same class
CommonClass
so you will still be reusing that class. In this way we won't have to alter theNavigationBar
during the execution time which can be messy.Then, you can send the necessary initialization information for your
CommonClass
having a method on yourCommonClass
that will load the appropiate information/data according to the selected tabBarItem, you can do that on theviewDidLoad
method.as the following:
In this way you will be doing the customization of your tab bar in just one part of your code and as you won't be altering it in execution time you won't need to customization in other parts causing flickering.