Two tab bar items should show the same UIViewContoller - ios

What I want is to have two UITabBarItems in my UITabBar (thats not really the problem...).
So normally the first item has his own an UIViewcontroller and the second item has his own UIViewcontroller.
But I want that each TabBarItem shows the same UIViewcontroller instance.
(the functionality is nearly the same, only one label is different between those two viewcontrollers)
So I think I have to push the last viewController on top of the tabBarItemStack right after the user pushed the second tabBarItem, right ?
At the moment I'm using a StoaryBoard with two UIViewcontroller, so I really don't know how I can access the TabBarItemStack and where do I get the notification that the next tab is pushed by the user ?
Or can I alter the stack after loading the first view and push the current view on the second index of the stack ?
Hope I was able to explain my problem so anybody would understand ;-)
Thanks and Regards,

I wouldn't use the UITabBar at all in this case. I would make some GUI-object in my viewcontroller that looks like two tabs, but is acually just 2 buttons.
When you click them you switch their look so that it looks like you have switched tabs, by changing the images of the buttons. But you are always staying in the same viewcontroller all the time. And you just change the content in it.
Then you can keep track class which "tab" the user has selected by using member variables and that way you know which content to show.
The UITabBar is most useful when you have an unknown amount of tabs and you don't know exactly what they will contain. There are many times it is a lot easier to not use the UITabBar and just images/buttons with "tab-looking" layout, even when you have more than one viewcontroller.

Could you have two UIViewControllers (one for each UITabBarItem), but they are both inherited (descended) from a third (Which contains all the logic). That way you are not duplicating the code, and not faffing with the hierarchy, such that you might introduce bugs?

Load same UIViewController in both TabBar. I assume u need to hide label in first tabBar and show in second tabBar
Now in viewWillAppear Method add this code:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(self.tabBarController.selectedIndex == 0)
{
yourLabel.hidden = YES;
}
else if(self.tabBarController.selectedIndex == 1)
{
yourLabel.hidden = NO;
}
}

Related

Reset current NavigationController and present another tab

I have an app (with a UITabBarController) that can reach the final payment view via two tabs, each with their own NavigationController.
(The illustration only shows the two tabs in question)
When payment is successful I want to reset both NavigationControllers and present tab 1.
If I was on tab 1 I could just use this code:
self.navigationController?.popToRootViewControllerAnimated(true)
But if I was on tab 2 that only brings me to the first viewController in navigationController in tab 2...
How can I present another tab while also resetting the NavigationController I am on (and others)?
Any help is very much appreciated. Thank you !
1) Create a custom UITabBarController or make a category that has a method called something like: completePayment()
- (void) completePayment
{
[self setSelectedIndex:n] // n is the index of your destination tab
[[[self viewControllers] objectAtIndex:m] popToRootViewControllerAnimated: YES]; // reset the stack in the current tab
}
2) trigger this method from the ViewController that the paymant is done as such:[self.tabbarController completePayment];
3) Profit!
There are probably ways of doing this in somewhat hacky ways, but what I will suggest you is that you reconsider your flow when you ask yourself a question like this one. Each UITab is designed to hold a UINavigationView that is self contained and independent from other UITab elements. If you force reset a tab that you are not on, you are breaking the flow and confusing the users.
So I recommend you push your Payment ViewController, wherever you need it in the app. And don't mess with other Tabs states.

Switching between UIViewControllers in story board

As someone who usually used separate xibs in the past I thought I'd give storyboard a go as it seemed a lot simpler to use and much easier to develop with. I've been writing an application where the essential set up is this:
At the top of all this is a UINavigationController (first level). Then I have Multiple UIViewControllers (second level) with buttons in them which you can tap to switch between the second level UIViewControllers.
However a problem occurs when I start switching between the second level UIViewControllers. I first thought this was an initialisation problem with the NSMutableArrays because in my code I have a NSTimer set to loop periodically and found when I set a breakpoint during it, when I went forward to the next timer tick event there appeared to be different instances of the same NSMutableArrays and it seemed a gamble to try and insert new values into these array with it sometimes working, sometimes not (as it may or may not insert into the correct instance).
Then, looking at the memory usage under Debug Navigator I found the issue. Each time I "switched" between the UIViewControllers a new UIViewController was being initiated, along with all new variables.
The code I am using to switch between them is
-(void) perform {
[[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:NO];
}
Or essentially a push segue transition. This also explains why when I tried to switch back to my view, the data on that view was lost as it is a complete new view.
Does anyone know how to switch between multiple ones of these UIViewControllers (say 5) essentially like a UITabViewController would except without the tab bar being present?
First option you can do this: You can use a tabbarcontroller for switching viewcontroller and hidden the tabbar. Then on buttonclick setthe tabbar index.
Second option you can do this: Create one more view controller and in this viewcontroller subview the all switching viewController and when you want to switch viewcontroller just bring that viewcontroller view to front by delegate.
Do you need the navigation bar and other features provided by your top level navigation controller?
If not, you could use a UIPageViewController instead.
You set up all your second level view controllers and then just have to tell the page view controller which one to display.
If you implement the associated delegate methods, it will automatically provide swipe gestures to switch between them and nice animations to get them on and off screen.
You can also get it to put a UIPageControl at the bottom showing a dot for each VC with the dot for the current VC highlighted.

Switching between UIViewControllers with UISegmentedControl

Right I have looked at a few SO questions on the subject and I am finding it difficult to come up with the correct solution here.
Requirements
I have a UITabBar based application. One of the tabs has a UINavigation controller with UISegmentedControl at the top allowing the user to switch between three different views.
Each view will have a UITableView which will allow the user to navigate to another view. These views should be pushed onto to the navigation controller.
Problem
Now all the SO questions and Answers on the subject show how to switch between views. However I need the view I switch to, to allow pushing of another view onto the navigation stack. I am not sure this is even possible. I thought about UIViewController containment - however that would show a view being pushed onto the stack in a smaller window that the screen's bounds. Not what I am looking for.
Any ideas how I can solve this with storyboards and UIViewControllers?
UPDATE
Here is what I am trying to do: In the screenshot the container area is where I need to load other view controllers into. The UISegment control cannot go into the navigation bar as that space is used for something else. So that's why I think UIViewController containment might be better here?
So even though this isn't using separate TableViewControllers, you can use different custom UIViews that are hidden by default and become visible when you select it's corresponding button. This will unfortunately make it so you have all three view's logic in the same VC.
To get around this, you can try setting up some delegates and mimicking the TableViewController logic separation by sending out the didSelectTableAtIndexPath, UIGesture touches, etc into classes outside the ViewController to help keep your code cleaner.
User UITabBarController and hide the tab bar.
- (void)viewDidLoad
{
self.tabBar.hidden = YES;
}
Binding the segment control with method valueChanged
- (void)valueChanged:(UISegmentedControl *)seg
{
if ([seg.selectedSegmentIndex == 0]) {
self.selectedIndex = 0;
} else if ([seg.selectedSegmentIndex == 1] {
self.selectedIndex = 1;
}
}
I achieve this by this way, I hope this will help.

iOS: Hide rootViewController of SplitView in TabBar app

I have a TabBar iPad app with a Split Controller in first tab. I follow this instructions to make it:
http://www.iphonedevsdk.com/forum/iphone-sdk-development/62217-simplest-way-make-split-controller-tab-bar-controller.html
Now my goal is to hide the root view controller of the split controller. I found a method to accomplish this:
http://vimeo.com/13054813
But that doesn't works for me, because it only works assuming the split controller is in the MainWindow.xib. But with the previous method, the split controller is added programatically.
Can someone help me to get my goal? Any idea would be appreciated.
Thanks in advance!
Here are the code:
http://dl.dropbox.com/u/27695108/MariCruz.zip
I hope you can help me.
Thanks!
You have a couple of problems with your project.
1 First one is that you are using a UITabBarController, that is why the code you found to hide the root view controller does not work.
Second one lays with your implementation of makeSplitViewController, where you are initializing twice your splitViewController, rootViewController, and detailViewController.
So, you have to fix point 2, so that you can correctly manage all of those controllers and then you should modify toggleSplitView so that you take into account the fact that you are using a UITabBarController. For example, replace the first few lines of that method with the following ones:
- (void)toggleSplitView {
NSArray *controllers = _tabBarController.viewControllers;
UIViewController* controller = [controllers objectAtIndex:1];
if (controller.view == splitViewController.view) {
[splitViewController.view removeFromSuperview];
splitViewController.viewControllers = [NSArray arrayWithObjects:rootViewController, rootViewController, nil];
splitViewController.view = detailViewController.view;
} else {
....
As you say, I am no accessing _window to check if the UISplit is there, because that view is not under _window, rather it is in the tab bar. The other branch of the if also needs to be rewritten according to the same criteria, but I will leave it for you.
The above code will work only with your second tab (the one corresponding to index 1); indeed, since you are overwriting splitViewController in makeSplitViewController, I can only use the element at index 1 in the tab bar without making further changes.

iOS: Setting text in nib subview from view in UITabBar/UINavigationController application

I'm having a problem getting a UISearchDisplay's text value to be set programatically on load of the view by another view and my question is have I overcomplicated my problem and missed something or am I on the right track of thinking.
Here's the situation: I have a UITabBarController as my root view, there are 2 tabs, both have a UINavigationController setup so I can push views as needed.
Tab 1 has a UITableViewController which is populated with a list of categories.
Tab 2 has a MapView in it's main view but I have done a custom UINavigationItem view to put various buttons and a UISearchDisplay on the rightBarButtonitem area.
The mapview layout and custom navigation item are stored in the same nib as two separate view objects. In Tab 2's viewDidLoad(), I initialise the rightBarButtonItem programatically with:
UIBarButtonItem *btnItem = [[UIBarButtonItem alloc] initWithCustomView:buttonBar];
self.navigationItem.rightBarButtonItem = btnItem;
[btnItem release];
Everything fires up, buttonBar is wired up to an IBOutlet as searchWhat and I can talk to this object from within the mapview's controller class.
If the user is in Tab 1 and taps a cell, I want it to switch to Tab 2 and populate the searchWhat.text and then execute the search code as if someone had typed in the search themselves.
What i'm having trouble with is the order of load and populate on a view.
I can access the 2nd tab from the 1st without any problem and get it to appear with something like:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Quick Category cell tapped at row %d", indexPath.row);
self.tabBarController.selectedIndex = 1; // change to the search view controller
//[self.tabBarController.selectedViewController viewDidAppear:YES];
UINavigationController *nav = (UINavigationController *)self.tabBarController.selectedViewController;
SearchViewController *srch = [nav.viewControllers objectAtIndex:0];
//NSLog(#"%#", [srch description]);
[srch queueSearchByType:kSearchTypeQuickCategories withData:[catList objectAtIndex:indexPath.row]];
[srch viewDidAppear:YES];
}
Don't worry about catList and SearchViewController, they exist and this bit works to switch tabs.
Here's the problem though, if the user starts the application and selects an item in tab 1, tab 2 appears but the values of the search display text don't get set - because viewDidLoad and viewDidAppear are called in another thread so the execution of queueSearchByType:withData: gets called while the view is still loading and setting up.
If the user selects tab 2 (therefore initialising the subview) and then selects tab 1 and an item, it can populate the search display text.
I can't just change the order of the tabs so that tab2 is first and therefore loads it's subviews to the navigation bar as the project specification is category search first.
Have I missed something very simple? What I need to do is wait for the second tab to fully appear before calling queueSearchByType:withData: - is there a way to do this?
At the moment, i've implemented a queue the search, check for a queue search approach, this seems to be a bit long winded.
Ok, I don't like answering my own question but it appears my fears were right, basically if you want a UINavigationItem that is a custom view (ie, to put a search bar and various other buttons up on the nav controller) and be able to switch to and populate them from another tab on a tab bar controller, then you need to put the subview in it's own class which is a subclass of UIViewController and then make delegation your friend (which it already is), i've provided an example in case anybody needs to repeat it which i've put on my blog HERE.
http://www.jamesrbrindle.com/developer/ios-developer/howto-add-a-custom-uinavigationitem-to-a-uinavigationcontroller-with-delegation.htm
If anyone disagrees and thinks this can be simpler, please let me know or rate this post

Resources