I'm starting out with iOS Development.
Currently, I've implemented a TabBarController that nests 2 Views, one of which has a TableView within in.
I'm trying to get the table view to Push another view when DidSelectRow is called.
What I am trying to do is similar to the AppStore in the Search Tab.
I.E:
When you find the App you want you tap on the table row - then the search bar fades away and the Navigation bar fades in, revealing more detail.
Right now I'm trying this:
self.nav = [[UINavigationController alloc] initWithRootViewController:rootVC];
nav.delegate = self;
self.detailView = [[detailView alloc] initWithNibName:#"detailView" bundle:nil];
[nav pushViewController:self.detailView animated:YES];
Where rootVC is the viewController in my secondView.
This does nothing. I've called NSLog to make sure that the method is being called, and it is.
Any help is greatly appreciated.
Thanks!
Do you have a navigation controller in the app? One way to achieve the navigation controller with tab bar controller is to add navigation controller for each tab bar item . Then make the root view controller of the navigation controller one of your 2 views controllers.
Related
I'm new to xcode ios 7.
I've struggling a lot with navigation controls building app for iPhone ios7.
I don't want to use storyboard. I prefer to do it programmatically.
What i am trying to do.
I know how to create NavigationBar & Navigation Toolbar via AppDelegate.m
But if it's possible i don't want to do it, because let's assume i want in FirstViewController to show just simple button "Go to Second View Controller" (No Navigation Bar or Toolbar here).
And now in SecondViewController i want to create Navigation Toolbar (bottom) with 4 different tabs linking to ViewControllers!
But the trick is, i want to maintain different Navigation Bar (top) for every ViewController (as you can see in this screenshot).
Here is my Xcode Project File
And here is screenshot form Fancy app showing what i am trying to achieve.
Thanks a lot in advance!
Just to give you an idea, When you tap the button on your first view controller, you can create a UINavigationController and set your second view controller as its root view controller. This way, your first view controller remains no nav bar view and the second view controller holds a Navigation controller. Try something like below:
-(IBAction)goToSecondVC:(id)sender // An action for the button in your first VC
{
SecondViewController *secondVC = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil]; //Init with second view controller
UINavigationController *secondNavVC = [[UINavigationController alloc] initWithRootViewController:secondVC]; // create a navigation controller and set the root as your second view controller
[self presentViewController:secondNavVC animated:YES completion:nil]; // and then present it with anim or no anim..
}
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 setup a UINavigation controller that uses the AppDelegate as the main point of contact.
I have different methods which run such as presentHomeViewController, presentLoginViewController, which push the different view controllers to the Navigation Controller.
App Delegate - didFinishLaunching
welcomeViewController = [[MyWelcomeViewController alloc] initWithNibName:#"MyWelcomeViewController" bundle:nil];
navController = [[UINavigationController alloc] initWithRootViewController:welcomeViewController];
navController.navigationBarHidden = YES;
self.revealSideViewController = [[PPRevealSideViewController alloc] initWithRootViewController:navController];
[self.revealSideViewController setDirectionsToShowBounce:PPRevealSideDirectionNone];
[self.revealSideViewController setPanInteractionsWhenClosed:PPRevealSideInteractionContentView | PPRevealSideInteractionNavigationBar];
self.window.rootViewController = self.revealSideViewController;
Is this the correct process for this?
- (void)presentHomeViewController {
// We start by dismissing the ModalViewConrtoller which is LoginViewController from the welcomeview
[self.welcomeViewController dismissModalViewControllerAnimated:YES];
// Check if the home view controller already exists if not create one
if (!self.homeViewController) {
NSLog(#"presentHomeViewController- Creating the Home View controller");
homeViewController = [[MyHomeViewController alloc] initWithNibName:#"MyHomeViewController" bundle:nil];
}
// Push the homeViewController onto the navController
NSLog(#"presentHomeViewController");
self.navController.navigationBarHidden = NO;
[self.navController setTitle:#"Home"];
[self.navController pushViewController:homeViewController animated:NO];
If I then add the following to a different class :
[self.navigationController pushViewController:accountViewController animated:NO];
No view is pushed to the stack, should I control all the movement within the AppDelegate as I have been doing, or is there betters way to approach this?
EDIT
Thanks for posting your code. So, to address your final question first, I don't recommend controlling your navigation stack from the app delegate. You should be controlling the stack from the view controllers that are the children of the navigation controller.
To that point, remember the hierarchy of view controllers: UINavigationController inherits from UIViewController, and UIViewController has properties defined for all the things you'd see in a navigation layout such navigation items and title. More importantly, it also has properties for its parent view controllers, the view controller that presented it, and its navigation controller. So, considering the hierarchy, your app delegate should only instantiate the navigation controller's root VC and the nav controller itself, and then subsequently set the nav controller's root VC.
From there, you should be pushing and popping other VCs from the VCs themselves. Remember, every VC has a property that's automatically set to point at the navigation controller it's a part of. That's why [self.navigationController pushViewController:] works. For instance, if I have a nav controller whose root VC is a UITableViewController, and tapping on one of the items in the table view pushed a new VC onto the stack, I would push that VC from the table VC and not from the nav controller class or the app delegate.
Sorry if that's confusing. Please let me know if that needs clarification and I'll give it my best. Otherwise, hopefully that gets you on the right track.
I have an application that looks like this;
Navigation Controller->Table View Controller->Navigation Controller2->Table View Controller2
The problem that I'm facing is that I want to have a "Back" button on Table View Controller2 that will take me back to the very first Navigation Controller. I can't figure out how to do this for the life of me, except by placing a button in the Table View Controller2's Navigation bar and creating a modal seque back to the first navigation controller. I don't think Apple will like that though. Can anyone help?
Try this:
NavigationController *nav = [[NavigationController alloc]init];
[self.navigationController pushViewController:nav animated:YES];
[nav release];
Design requirement:
Show a list of items the user can pick from
After having picked an item, bring the user to a new view with a back button. The new view should contain a list of tabs at the bottom that are not present in the first screen
When clicking an item in the tabs, a new screen should appear with a back button and the tabs should still be visible at the bottom.
Clicking a tab should take the user back up the hierarchy to #2. Not to the first screen.
I have tried following structure:
UINavigationController
UIViewController with a UITableView
UIViewController with a UITabBar (like here http://www.wiredbob.com/2009/04/iphone-tweetie-style-navigation.html)
and also
UINavigationController
UIViewController with a UITableView
UITabbarController
Both cases work fine with displaying the UITabBar, but when I click an item in one of the tabs and push a new UIViewController, then the tabs at the bottom disappears. I want the tabs to remain in place for all pushed UIViewControllers that occurs inside a tab of the UITabBarController.
A related question is this one but it doesn't deal with the problem of pushed viewcontrollers inside a tab:
Tab bar controller inside a navigation controller, or sharing a navigation root view
Do I need to change the rootcontroller to the UITabController? Anyone actually implemented this?
Here is the correct structure:
UITabBarcontroller (UIWindow's rootViewController)
->UINavigationController (first tab)
-->UIViewController
->UINavigationController (second tab)
-->UIViewController
It sounds like you want to change the layout of your view hierarchy to accommodate your requirements. You should present your view controllers as such:
UITabBarController -> UINavigationController -> UIViewController
In your app delegate, you can implement this programmatically using something along the lines of:
UIViewController *viewControllerOne = [[[UIViewController alloc] init] autorelease];
UINavigationController *navigationControllerOne = [[[UINavigationController alloc] initWithRootViewController:viewControllerOne] autorelease];
UIViewController *viewControllerTwo = [[[UIViewController alloc] init] autorelease];
UINavigationController *navigationControllerTwo = [[[UINavigationController alloc] initWithRootViewController:viewControllerTwo] autorelease];
UITabBarController *tabBarController = [[[UITabBarController alloc] init] autorelease];
[tabBarController setViewControllers:[NSArray arrayWithObjects:navigationControllerOne, navigationControllerTwo, nil]];
[[self window] setRootViewController:tabBarController]
I haven't checked the above, it's just written from memory but should do what you require as an example.
Using this format, you can push any additional view controllers on to the navigation controller stack without your tab bar disappearing.
If you want to push this view hierarchy without having the tab bar controller as your root view controller, simply push the tab bar controller instead of setting it as the root view controller in the app delegate.
Hope that helps!