I had one nav bar controller, which I embedded in a tabbar controller. I then put two more nav bar controllers onto the story board and created push segues from the tab bar controller to the two new navbar controllers, so I expected the log statement below to be 3, for the number of view controllers on the tab bar controller, however, it logged 1. The last line of code below also obviously threw an out of bounds error because there is no objectAtIndex:1 . Can you explain? Why aren't the second and third navbar controllers that I created push segues to in storyboard present in the viewControllers property of the tab bar controller?
UITabBarController *tbc = (UITabBarController *)self.window.rootViewController;
NSLog(#"tbc %lu", (unsigned long)[[tbc viewControllers] count]);
UINavigationController *nav = (UINavigationController *)[[tbc viewControllers] objectAtIndex:0];
UINavigationController *nav2 = (UINavigationController *)[[tbc viewControllers] objectAtIndex:1];
The problem was that when I connected the tab bar controller to the 2nd and 3rd navigation controller in the storyboard, I created a "push" segue. However, it has to be a "relationship" segue between the tab bar controller and whatever view controllers it's connected to.
Related
I have three view controllers (vc1, vc2, vc3) and two navigation controllers (nav1, nav2).
nav1 is the entry point of the storyboard.
vc1 is the rootViewController of nav1.
vc2 is the rootViewController of nav2.
nav2 is presented from vc1 through nav1.
Now when I tried to present vc3 from vc2 through nav2, navigation bar is not showing.
You need to present your controller with navigationController.
ViewController *objVC = [self.storyboard instantiateViewControllerWithIdentifier:#"viewcontrollerid"];
UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:objVC];
[self.navigationController presentViewController:navController animated:YES completion:nil];
Now, the way iOS works, it will never give you an instance of your navigation controller in a presented view controller because when you present a view controller, it is not added to the viewcontroller stack of the navigation controller.
The reason you can see the navigation controller in the other two is because your'e presenting the navigation controller itself and not view controller.
I try to push to specific view controller from app delegate without losing previously set navigation bar and tab bar items setup.
As presented in my Main storyboard:
After 1 action performed in TypeNameVC, on app relaunch I want to skip LogInVC and TypeNameVC in didFinishLaunchingWithOptions in AppDelegate forward to MapViewController or any other VC of Tab Bar Controller.
This code initializes new Navigation Controller with new Navigation Bar and Tab Bar Controller is missing.
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
//To instantiate Main.storyboard.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
//To instantiate VC to go to.
MapViewController *mapVC = (MapViewController *)[storyboard instantiateViewControllerWithIdentifier:#"MapViewControllerID"];
//To push to instantiated VC.
[navigationController pushViewController:mapVC animated:YES];
I tried to performSegue using segue to Tab Bar Controller but on Navigation Controller stack there is only LoginViewController (I checked it with [navigationController viewControllers])
I read through entire Stack Overflow, I made dozens of combinations but I can't figure out the solution. I would appreciate any help/advice.
UPDATED QUESTION
Screen: screen
Have a look to the screen image. First row of screen shows how it looks like if I navigate "normally". Second row shows what happens if I push to MapVC from AppDelegate. What I need is to skip first two VC's with maintaining Navigation and Tab Bar bars setup.
When I navigate "normally" Tab Bar Controller and it's VC's get correctly allocated.
2016-06-08 12:37:44.394 Checkpoint[4196:1034786] Navigation Controller VC's: (
LogInViewController: 0x135d50b00,
TypeNameViewController: 0x135f455b0,
UITabBarController: 0x135f1d180
)
2016-06-08 12:37:44.394 Checkpoint[4196:1034786] Tab Bar Controller VC's: (
MapViewController: 0x137078cf0,
PlacesTableViewController: 0x135f1d7d0,
FriendsTableViewController: 0x137083350
)
When I push directly to MapVC they don't. I do get the point what's going on but I know how to code that solution.
Navigation Controller VC's: (
LogInViewController: 0x15fd5ccf0,
MapViewController: 0x15fd6ffa0
)
2016-06-08 12:31:53.813 Checkpoint[4187:1033755] Tab Bar Controller VC's: (null)
Customize your class MapViewController for visible Navigation Bar and Tab Bar:
- (instancetype)init
{
// init code
self.hidesBottomBarWhenPushed = NO;
retur self;
}
-(void)viewWillAppear:(BOOL)animated
{
// some code
[self.navigationController setNavigationBarHidden:NO];
}
I have a tab bar controller with 4 tabs and each tab is their own UINavigationController, which is how you're supposed to nest tab bar and navigation controller's together. The initial tab is a TableViewController and works/appears the way that it should. From the tableVC I can push standard view controller's onto the navigation controller with:
[self.navigationController pushViewController:VC animated:YES];
and it works properly.
If I attempt to push another TableViewController onto the navigation with the same method it works the same way, but the initial tab bar does not get pushed off screen like it should, it just stays in place.
Why would the tab bar stay on screen even though I am pushing a new VC onto the navigation?
I have tested with multiple instances of different TableVC's and it only happens with a table view controller.
Here is the code I'm using:
- (void)pushTableVC
{
TestTableVC *tableVC = [[TestTableVC alloc] init];
[self.navigationController pushViewController:tableVC animated:YES];
}
This will push the new table view onto the stack, but the tab bar from the parent VC stays in place and does not get pushed off screen like it should.
You should call the method setHidesBottomBarWhenPushed: on the view controller you are pushing to correctly hide the tab bar.
UIViewController *viewController = [[UIViewController alloc] init];
[viewController setHidesBottomBarWhenPushed:YES];
[[self navigationController] pushViewController:viewController animated:YES];
When you use a UITabBarController, the tab bar always stays on screen, even as you push additional view controllers onto an embedded UINavigationController. You will see this in any app that has a UITabBarController implemented, unless they implement custom behavior to change this.
The UINavigationController contains everything above the UITabBar, but does not contain the UITabBar itself, so it would not be able to push it offscreen.
I have a tabbar application and I would like to add navigationcontroller to a non-rootviewcontroller.
Is it possible?
Thanks for any help.
UPDATE 23:10 GMT+2
UINavigationController is a subclass of UIViewController, as such you can present it or you can add its view as a subview (assuming you then don't release the UINavigationController instance itself which would have interesting side effects).
What you can't do is to push the navigation controller into some of the provided container view controllers. Like pushing a navigation controller into another navigation controllers stack.
Each Tab in Tab Bar Controller can have a custom view controller. Where your custom view controller can be a navigation controller.
But, in a navigation controller, if you wish to add a navigation controller on lets say tap of a tableview cell, you will have to present it modally on navigation controller. You can not push a navigation controller into another navigation controller.
for eg.
Instantiate your root view controller for the navigation controller you wish to present
YourAnotherRootVC *anotherVC = [[YourAnotherRootVC alloc] initWithNibName:#"YourAnotherRootVC" bundle:[NSBundle mainBundle]];
Instantiate UiNavigationController
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:anotherVC];
Present it to current navigation controller.
[self.navigationController presentModalViewController:navController animated:YES];
Hi I added a prepare for segue code in order to transfer information, however I'm getting an error.
I have a tab bar controller. It has 4 tabs. Each tab has a navigation controller, and a VC as a root view controller.
from tab 1-->nav controller-->VC 1 I need to take a value to tab2-->nav controller --->VC1
(also is the segue connected to the nav controller at tab 2, or the root view at tab 2)
Thank you in advance
error:customizableViewControllers]: unrecognized selector sent to instance 0xf19bd60
(but I am going to tab 2 (index 1))?
where is my error?
if ([segue.identifier isEqualToString:#"ResultsSegue"])
{
//the root VC at tab 2
ResultsIndexViewController*controller=[[ResultsIndexViewController alloc]init];
UITabBarController *tabController = [segue destinationViewController];
controller = (ResultsIndexViewController*)[[tabController customizableViewControllers]objectAtIndex:1];//crashing here
controller.resultsArray=[NSMutableArray arrayWithArray:_matchedResultsArray];
}
}
This part of your code
[1] UITabBarController *tabController = [segue destinationViewController];
[2] controller = (ResultsIndexViewController*)[[tabController customizableViewControllers]objectAtIndex:1];//crashing here
Is full of misconceptions.
In [1] you are assigning a destinationViewController (type UIViewController) to an object of type UITabBarController. This is compiler-legal (UITabBarController inherits from UIViewController so they are both of type UIViewController) but it doesn't reflect really what is going on. Your segue will be to the UIViewController or it's UINavigationController.
So in line [2] when you try to use your tabController as a tab bar controller, it crashes (because it isn't one).
You need to redesign your project... forget the Segue, and use the tab bar controller. Something like...
- (IBAction)moveToTab2:(id)sender {
ResultsViewController* resultsVC = (ResultsViewController*)
[[self.tabBarController viewControllers] objectAtIndex:1];
resultsVC.resultsArray=
[NSMutableArray arrayWithArray:_matchedResultsArray];
[self.tabBarController setSelectedViewController:resultsVC;
}