I have two tabs in my app, the left tab is a normal UIViewController, right tab is a navigation controller with a table view inside it. I'd like to allow the user to press a button on the left tab and jump to a specific detail view that belongs to a specific row in the table view on the right tab.
In the table view itself I have no problems displaying a specific detail view eg:
[self.navigationController pushViewController:theView animated:YES];
and I can also jump tabs using
self.tabBarController.selectedIndex = 1; // 1= right tab
but I cant figure out how to do both. I've tried
self.tabBarController.selectedIndex = 1; // 1= right tab
// alloc and init theView here
[self.navigationController pushViewController:theView animated:YES];
but that doesnt work.
EDIT:
when I try the above code it just switches tab but doesnt push the view.
I also tried what criscokid suggested but nothing happens at all.
EDIT 2:
Trying to explain whats on each tab:
Root (Tab Bar Controller)
|
--(Left Tab)-- UIViewController (I want to go from here...)
|
--(Right Tab)---UINavigationController
|
---UITableViewController
|
----UIViewController (...to here)
^ specific view with data from specific row
in table view (that is 'theView' from above)
For me the correct way was:
UINavigationController * navigationController = (UINavigationController *) [[self tabBarController] selectedViewController];
[navigationController pushViewController:viewController animated:YES];
criscokid's answer has one redundant call to navigationController.
That's because your selectedViewController is actually a UINavigationViewController.
If you are switching the tab bar and pushing the ViewController onto the navigation controller stack in the same method, you wouldn't want to use self.navigationController. If I understand correctly you want to add it to a navigationController on the right tab. I believe you would want to use:
[[[[self tabBarController] selectedViewController] navigationController] pushViewController:theView animated:YES];
Related
So I have a tab bar app with three tabs. In the second tab, I have a button that loads another view in which two text fields pass their values into two labels in the original tab view. When I click the button, enter my values, and click the set button to go back to the original view, the labels are changed, but the tab bar doesn't load. How do I load the tab bar after switching from a different view?
Code for when the button in the original tab bar view is pressed
TeamNameViewController *fvc = [self.storyboard instantiateViewControllerWithIdentifier:#"99"];
fvc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:fvc animated:YES completion:nil];
Code to go back to tab bar
SecondViewController *tempView = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerSB"];
tempView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:tempView animated:YES completion:nil];
The short answer is: You don't.
presentViewCntroller:animated:completion presents the target view controller modally. The other views still exist and you don't need to instantiate them again, you need to dismiss the modal view controller.
You need to call dismissViewController:animated:completion on the presenting view controller (that is the view controller that calls presentViewController:animated:completion is responsible).
Everyone
I have a problem and I have been searching the solution but could not find any. I am working on a tab bar based app. Problem is that I want to hide tab bar at first screen and then show it on all other screens that are being displayed after first screen.
Can anyone please give me the best solution for this problem?
Actual scenario is that I have a screen that is login screen. Now i dont want to show tab bar here as tab bar will be displayed only if the user is signed in. When user logs in, I want the tab bar to be displayed showing its contents.
Best Regards
If you have your Tab Bar Controller as your rootController, you can use rootController.selectedIndex =0 for selecting 1st Tab bar Item, and rootController.selectedIndex =1; and so forth.
As soon as that particular view loads, you can load the other views in an array, and then add it to the rootController.selectedIndex and reloadInputViews with animation.
Edit: (as per the comments)
So you have a tab bar controller, and you want to show the introduction and the login screen while starting the App. If login is successful, you want to present the tab bar controller ! This can be done with ModalViewControllers
In the ViewDidLoad of the view that loads up first, (it's your first tab by default), add
//Declare Introduction Screen//
IntroductionController *introductionController = [[IntroductionController alloc] initWithNibName:#"IntroductionController" bundle:[NSBundle mainBundle]];
//Give a navigation screen for your introduction screen and set it to introduction screen
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:introductionController];
navController.title = #"Introduction";
navController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navController animated:NO];
Now your introduction screen would load as soon as your first tab bar loads. But the loading is instantaneous, so it's not visible to the user's eye. Now reference your Login View Controller like #class LoginController and create an object LoginViewController *lvc;, and synthesize it. Now declare LoginButton and in the IBAction
-(IBAction) loginAction: (id) sender{
NSLog(#"I clicked Login");
if (self.lvc ==nil){
self.lvc = [[LoginController alloc] init ];
}
lvc.title = #"Login";
[self.navigationController pushViewController: self.lvc animated:YES];
}
And in the LoginViewController, if Login is successful, just do
[self dismissModalViewControllerAnimated:YES];
create an outlet for the uitabbar, then declare it hidden in the first screen, then create a new void, NOT SENT SO IT DOESNT WORK in the first screen, make it say, lets say, hide. And inside hide, put code saying your uitabbar.hidden = YES; then, to make it work in the other view, write this in the viewDidLoad:
[(//first view*)[UIApplication sharedApplication].delegate //the void, in this case, hide];
I have this code in my table view controller (and delegate):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailStatus *detailViewController = [[DetailStatus alloc] initWithNibName:#"DetailStatus" bundle:nil status:[mStatuses objectAtIndex:indexPath.row]];
[[self navigationController] pushViewController:detailViewController animated:YES];
[detailViewController release];
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
NSLog(#"exiting didselectrow");
}
And in my DetailStatus class:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil status:(NSDictionary *)pStatus {
NSLog(#"I am being called %d", [pStatus objectForKey:#"id"]);
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// some stuff
}
return self;
}
The funny thing is, my DetailStatus is actually being initialised, in the console window, it even outputs "I am being called 000001" but strangely the view is not being pushed to the table view...
I've checked the nib name, and it's ok. I checked the DetailStatus heading file, it looks ok (like this):
#interface DetailStatus : UIViewController {
So does anyone know why the view is not being pushed to the window even if I've initialised it and pushed it?
UPDATE: I tried logging some debugging messages to viewDidLoad in DetailStatus, and it seems like the view is not loaded even though the class was instantiated... I wonder why.
UPDATE2: I have a feeling that this might be my navigation controller organisation that's wrong.. I have this following:
Login page -> customtabbar -> First table view -> DetailStatus
-> Second table view -> DetailStatus
I think I'm only maintaining one navigation controller in that hierarchy. I've never created other navigation controllers. I only push view after another.
Thank you everyone for the answers! I will give out the bounty soon, I'll let other people vote first before the bounty expires.
After looking at it,the scenario seems to be same like me.What I faced for the first time when doing Tab+Navigation.
I am sure that there is some problem with your Tab+Navigation based application.
Although it shows the Tab as well as navigation are not able to navigate the basic flow.And it is very difficult to solve your problem with such less code.
Instead of this, I had an alternate solution for the same:
Once you have a tab bar in a XIB, the easiest way to approach this is to drag a UINavigationController object over from the Library window (looks like a left nav bar button on a gold background) into the Tree View for your tab bar (the text only view, not the GUI). Place it under the tab bar, then drag your existing view controller under the tab bar controller instead of under the tab bar.
When you go to view that tab you should then see a navigation bar on the top of it... if you are loading the navigation controller from another xib, you'll modify the nav bar in the tab bar xib.
else you can below you can follow the best url for the same:
http://books.google.co.in/books?id=2yYlm_2ktFYC&pg=PA179&lpg=PA179&dq=navigation+with+the+tab+based+application+iphoneSDK&source=bl&ots=nf2YYjX5Am&sig=COpHj9wOtsDChQBglpsljSTsElw&hl=en&ei=3ZoFTeGSOI_tsgbc_Iz6CQ&sa=X&oi=book_result&ct=result&resnum=6&ved=0CDAQ6AEwBQ#v=onepage&q&f=false
http://www.youtube.com/watch?v=LBnPfAtswgw
Hope this will surely solve your problem.
Unless the UINavigationController is the immediate parent of your table view controller, [self navigationController] will return nil.
I'm unclear exactly where it lies in the view controller hierarchy, based on your explanation, but I suspect you might have your UITabBarController nested within the navigation controller, when it should be the other way around. If, by chance, you actually mean to push the tab bar off screen (and thus you do want the tab bar controller nested within the navigation controller), you will need to call something like the following:
UIViewController *parentViewController = self.parentViewController;
[parentViewController.navigationController
pushViewController:detailViewController
animated:YES
];
P.S. Once the push is working correctly, you won't need to deselect the tapped row, as UITableViewController does this automatically when the view reappears.
I not seen putting status on the end of the init of the view. Guessing that's something you added.
Dont you just need to do [self pushViewController etc instead of the navigationController bit
Could it be that the nib is not wired up correctly. I.e. In the nib there is no connection between the view and the controller so even though the controller is pushed correctly, the navigation controller cannot find the view.
Just a guess!
You need to implement like above In tab controller put navigation controller according to your tabs and in navigation controller you can put your tab item.And also you need to set tab bar item nib file.then on tapping a tab you get tab screen and because of navigation controller you can easily navigate.even you can navigate on the screen of any tab main screen.
This is the way which you need to implement.
It definitely helps you but you need some logical implementation.
Is your tableViewController directly pushed to the navigation controller or is there another viewController in between ? Check the value of [self navigationController] against the value of your navigationController (from the place your actually instanciate it)
Once check that have you initialized the First Tableview and Second TableView with Navigation controller or not.
While adding to the tabBar, have you added the UINavigationController or only the UIViewController object.
PM_FirstNavigationController *First_navController = [[PM_FirstNavigationController alloc] initWithRootViewController:FirstTableViewController];
tabBarController.viewControllers= [NSArray arrayWithObject: First_navController];
You have to add the view controllers to the tabBar's like that.
Then while calling the [self navigationController], it will give navigation controller object.
Regards,
Satya
I have two tabs in my app, each of them is a UITableView, and each of the views in the two tabs has its own DetailViewController.
Now, if I click on a TableViewCell in the DetailViewController in the first tab, I want to jump to the DetailViewController of the second tab. I know how to access the second tab
self.tabBarController.selectedIndex = 1;
and I know how to access the DetailViewController, but only without jumping to the second tab.
Is it possible to access the second tab, and then access its DetailViewController?
It would be best if the main TableView in the second tab wouldn't be visible at all, so, it should jump directly to the DetailViewController of the second tab, with the navigation controller showing the "back" button to the main view controller and the second tab highlighted. Is this possible? And, if it is, how can I do this?
Thanks in advance :-)
The tabBarController has an array with the viewController of every tab. You can push the DetailViewController like this:
[[self.tabBarController.viewControllers objectAtIndex:1] pushViewController:detailViewController animated:NO];
Before that you might want to pop to the rootViewController:
[[self.tabBarController.viewControllers objectAtIndex:1] popToRootViewControllerAnimated:NO];
I am trying to get the same functionality as contacts app in iphone. The problem is following , when i hide navigationbar using following command
[self.navigationController setNavigationBarHidden:YES animated:YES]
It gets hidden throughout all viewControllers in navigationController stack.
I am implementing search in my application pretty much the same way it is in Contacts app. When user touches search field it hides navigationBar, but when user selects item from table view transition I want it to stay hidden in rootViewController and to be visible in pushed viewController.
I was thinking about completely hiding navigationControllers navigationBar and placing my own navigationBar, but i am not sure is it right direction to take.
add following code tot the desired view controller, and it will work fine
- (void) viewWillAppear:(BOOL)animated{
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
hope it helps.