pushViewController Not Displaying UIView/Nib with tabbar and nav bar - iphone

I'm relatively new to objective c but not programming and am stuck with my iphone app.
I created a nav based app with both a navbar and a tab bar controller. I set the tab bar as the root controller. I'm able to switch between each tab without any issues to various UIViews and UITableViews.
My issue is that in one of my UITableViews that I call from the TabBarController, didSelectRowAtIndexPath function is suppose to display a new UIView. The below code does not give any errors and runs fine but does not show the new Nib.
if(newViewController == nil) {
NSLog(#"yes nil");
BookViewController *aNewViewController = [[BookViewController alloc] initWithNibName:#"BookOptionView" bundle:nil];
self.newViewController = aNewViewController;
[aNewViewController release];
}
BookAppDelegate *delegate = (BookAppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.appNavBar pushViewController:newViewController animated:YES];
Now when I do the below, it works fine but it gets rid of the nav and tab which I'm assuming because its a modal call instead of pushing the view controller.
BookViewController *screen = [[BookViewController alloc] initWithNibName:#"BookOptionView" bundle:[NSBundle mainBundle]];
screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:screen animated:YES];
[screen release];
Any ideas why I can't get the View Controller to push correctly? In my application delegate file, I declared an AppNavBarController object (inherit from UINavigationController) called appNavBar.
Any help would be appreciated!

If you want to present your view as a modal view with nav controller, you can do it as below:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
[self presentModalViewController:navigationController animated:YES];
Also, from what I see, you have your navcontroller in your appdelegate. So I guess you are using a global navcontroller for all your tab views, which ideally shouldn't be the case. Your navcontroller should be within your tab controller and preferably you need to have different nav controllers in different tabs.

I actually found my answer. I'm not sure I understand why my code above doesn't work but the following accomplishes what I want:
[self.navigationController pushViewController:newControllerName animated:YES];

Related

don't understand how to use navigation controller in iphone

I'm extremly new to iphone and I have the following misunderstanding.
All over internet the tutorials about how to use NavigationController programatically it says:
NavigationController must be declared in applicationDidFinishLaunching and must be init with a root.After that you can add views to it.
I have this:
A UIViewController class meaning(AdiViewController.h, AdiViewController.m and AdiViewController.xib) and no Delegate file meaning no applicationDidFinishLaunching method.
What I wanna do is from my class-AdiViewController when pressing a button to go to another view.
I understand that I need a NavigationController which should retain my views having the root AdiViewController.
But my problem is where should I initializate that NavigationController in viewDidAppear??...cause I don't have the Delegate files.
If you could provide a minimal example with this small issue of mine it would be great.I'm sure that for those how are senior this is nothing but still I don't get it.Thanks
NavigationController must be declared in applicationDidFinishLaunching -> this is not true.
In your AdiViewController if you have button when you push that button you want to load navigation Controller right ?
// Hook this IBAction to your button in AdiViewController
- (IBAction)pushNavController
{
AnotherViewController* rootView = [[AnotherViewController alloc] initWithNibName:#"Anotherview" bundle:nil];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:rootView];
[rootView release];
[self presentModalViewController:navController animated:YES];
[navController release];
}
If you are in AnotherViewController i.e., you are in root view controller of Navigation controller. You need to push and pop view controllers from there. For example if you have a button in AnotherViewController:
// push next view controller onto navigation controller's stack
- (IBAction)pushNextViewController
{
NextViewController* nextView = [[NextViewController alloc] initWithNibName:#"NextView" bundle:nil];
[self.navigationController pushViewController:nextView animated:YES];
[nextView release];
}
// Similarly if you want to go back to AnotherViewController from NextViewController you just pop that from navigation controller's stack
- (IBAction)pushNextViewController
{
[self.navigationController popViewControllerAnimated:YES];
}

UINavigationBar refuses to show in Modal View Controller

I am loading a Modal view controller using the following code in my RootViewController:
[self.navigationController presentModalViewController:accountViewController animated:YES];
In the accountViewController xib file, I have set a navigation bar. My MainWindow.xib and RootViewController.xib also have the navigation bar setup correctly. Additionally, my app delegate has setup the navigation controller (I assume) correctly:
UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.navigationController = aNavigationController;
[window addSubview:navigationController.view];
However, when I load my accountViewController the UINavigationBar is nowhere to be seen. Is it not possible to show a UINavigationBar in a modal view? I was planning to use it to hide the back button, and add a right button...
sha's answer is correct, but I'm giving my own answer to expand on it with a code example to make it clear.
You probably want something like:
- (void)showAccountViewController
{
AccountViewController* accountViewController = [[AccountViewController alloc] initWithNibName:#"AccountView" bundle:nil];
...
// Initialize properties of accountViewController
...
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:accountViewController];
[self.navigationController presentModalViewController:navController animated:YES];
[navController release];
[accountViewController release];
}
You need to push not viewController but navigationController that has viewController inside.
You can also set the presentation style in the Attribute Inspector to "Current Context". Modal View will not cover the Navigational Bar.

Three20 TTLauncher Issues

So, I'm having some issues with my implementation of the Three20 TTLauncherView. I am using their code, not a fork (although I have heard of rodmaz's version), and I can't get it to work properly. This is what my app looks like.
alt text http://img709.imageshack.us/img709/8792/screenshot20100715at409.png
I removed the icon image, that's not the issue. The issue is, at the top there is no Navigation bar at all, and I believe also causes the white strip at the bottom, which appears to have the same dimensions as a Nav Bar. I've spent quite a while looking through their code and can't figure this out at all. It looks like their Navigation bar (as seen in their Catalog example app) stems from the TTTableViewController, or something further up. However, my app starts like the Facebook app does, not into a table, but into the TTLauncherView. So... how do I get the Navigation bar into my TTLauncher view, if it goes "App Delegate -> TTLauncherView Subclass"
Thanks for your help!
Edit:
Added the code I used. I put this in my app delegate, wrapping my first view with the UINavigation Controller, and it worked just as I wanted!
MainViewController *aController = [[MainViewController alloc] initWithNibName:nil bundle:nil]; //my Main view
self.mainViewController = aController;
[aController release]; //release for Memory Management
self.mainViewController.view.frame = [UIScreen mainScreen].applicationFrame;
UINavigationController *navigationController = [[UINavigationController alloc] init];
[navigationController pushViewController:self.mainViewController animated:NO]; //Gets the main view on the screen
[window addSubview:navigationController.view];
You simply wrap the view with a navigation bar before you push the new view. As an example, here is a snippet of my code where I present a modal view controller with a navigation bar.
- (IBAction) showNewNavView: (id) sender
{
// Present it as a modal view and wrap the controller in a navigation controller to provide a navigation bar for the Edit and Save buttons
ModalViewController *addController = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
addController.delegate = self;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addController];
navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[addController release];
}
If you want to add any buttons or set the title of it, you need to do that in the viewDidLoad method of the view that you are pushing (i.e. your TTLauncher view)

Accessing a Top Navigation Controller from a Subview Navigation Controller

I have a my views and controllers set up like so.
A Tab/Bar controller
Within 1. is a root view controller
within 2. is a programmatically created navigation controller, that is displayed as a subview in the root view controller.
What I am trying to do is access the top tab bar/navigation controller so that i can push a view onto it.
I tried parentViewController but all it did was push the view onto the programmed nav controller.
any suggestions?
This is how i set up my root view controller:
-(void)viewDidAppear:(BOOL)animated{
NSLog(#"ROOT APPEARED");
[super viewDidAppear:animated];
WorklistViewController *worklistController = [[WorklistViewController alloc]initWithNibName:#"WorklistView" bundle:[NSBundle mainBundle]];
UINavigationController *worklistNavController = [[UINavigationController alloc] initWithRootViewController:worklistController];
worklistNavController.navigationBar.barStyle = UIBarStyleBlackOpaque;
worklistNavController.view.frame = watchlistView.frame;
[worklistNavController.topViewController viewDidLoad];
[worklistNavController.topViewController viewWillAppear:YES];
[self.view addSubview:worklistNavController.view];
GetAlertRequestViewController *alertsController = [[GetAlertRequestViewController alloc]initWithNibName:#"AlertsView" bundle:[NSBundle mainBundle]];
UINavigationController *alertsNavController = [[UINavigationController alloc] initWithRootViewController:alertsController];
alertsNavController.navigationBar.barStyle = UIBarStyleBlackOpaque;
alertsNavController.view.frame = alertsView.frame;
[alertsNavController.topViewController viewDidLoad];
[alertsNavController.topViewController viewWillAppear:YES];
[self.view addSubview:alertsNavController.view];
}
A nested ViewController (ie, inside a view controlled by a ViewController that's actually on the NavController stack) doesn't have direct access to the UINavigationController that its parent's view's controller is a stack member of. That's one MOUTHFUL of a sentence, but the sense of it is: you can't get there from here.
Instead you've got to get at the app's NavController via the App delegate.
YourAppDelegate *del = (YourAppDelegate *)[UIApplication sharedApplication].delegate;
[del.navigationController pushViewController:nextViewController animated:YES];
You're using your UIApplication's singleton (contains all sorts of good info about your app), which has a .delegate property pointing to the AppDelegate, and that contains a reference to the NavigationController.
This is how the "Navigation-based Application" Xcode template sets up NavController ownership, anyway. YMMV if you rolled your own--though if you did, you probably wouldn't need to ask this question.
You can use the follow instruccion:
[(UINavigationController *)self.view.window.rootViewController pushViewController:vc animated:YES];
It works for me :D
Have a look at UIViewController's navigationController and tabBarController properties. These will return the corresponding navigationController or tabBarController that the given UIViewController 'belongs' to.
So you can do something like:
[customController.navigationController pushViewController:newController animated:YES];
// Similarly for tabBarController ...

popView from UITabBarController inside UINavigationController

I'm building an application based on the Utility template from Xcode, to which I have added some more views. My application structure would be as follows:
MainView (the app menu)
Flip-side view (a calculator)
UINavigationController
Settings view
viewDiDLoad: UITabBarController
- Tab1 view (options)
- Tab2 view (information text)
I can navigate correctly from my MainView to my Flip-side view, which is also the root view of the Navigation Controller. From my Flip-side view, I push a second view of my Navigation Controller (Settings view) that is configured to show an UITabBarController, with two tabs, as soon as it loads (with viewDidLoad).
If I remove the UITabBarController, I can return with no problems to my Flip-side view using "popViewController" from my Settings view. The problem comes if I load the UITabBarController in viewDiDLoad in my Settings view... the tabs work perfectly, but I'm not able to return to my Flip-side view (root view of the Navigation Controller) anymore.
I CAN return if I use the Navigation Bar of the Navigation Controller, but I want to configure my own buttons and have the Navigation Bar hidden.
So far I've tried the following methods:
[self.navigationController popViewControllerAnimated:YES];
[self.navigationController popToRootViewControllerAnimated:YES];
[self.navigationController popToViewController:FlipSideViewController animated:YES];
But they don't seem to work. The first two just do nothing (the screen remains as it was), and the third one does not recognize the "FlipsideViewController" (maybe because it's a delegate of the MainViewController?).
Is there a way to check what is exactly doing the "back" button of the Navigation Bar if I activate it?
Should I be using delegates?
Can I call a popViewController method in my Settings view from any of the two Tab views?
This is my Flip-side view:
- (IBAction)showSettingsView {
SettingsViewController *controller = [[SettingsViewController alloc] initWithNibName:#"SettingsView" bundle:nil];
controller.title = #"Settings";
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
This is my Settings view:
- (void)viewDidLoad {
[super viewDidLoad];
tabBarController = [[UITabBarController alloc] init];
Tab1ViewController* vc1 = [[Tab1ViewController alloc] init];
Tab2ViewController* vc2 = [[Tab2ViewController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:vc1, vc2, nil];
tabBarController.viewControllers = controllers;
[self.view addSubview:tabBarController.view];
}
And the method to return in one of the Tab views:
- (IBAction)backFromTab1View {
[self.navigationController popToViewController:FlipSideViewController animated:YES];
}
Thanks very much and sorry if the question is too basic!
I actually solved the problem creating my own UINavigationBar in the Settings view and using:
[self.view insertSubview:tabBarController.view belowSubview:myNavigationBar];
That inserts the rest of the view below the Navigation Bar and I still can use it to configure a button which pops the view and return to the previous screen.
It took me a while to realise the differences between "addSubview" and "inserSubview + belowSubview". Sorry about that!