Setting up a Navigation Controller with a Map View in Interface Builder - iphone

I'm trying to create a modal view which pops up when the user presses a button. The modal view has a navigation bar with a map view as the main view. I'm having trouble setting this up in Interface Builder. When I set the view outlet for my File's Owner's view to the view inside the Navigation Controller, the only thing that show up is the map view, with a grey space at the top and bottom. The navigation bar never appears. Here's a screenshop of how it looks, with an image of my IB window.
How can I get the navigation bar to show up properly? Thanks
alt text http://img.skitch.com/20100126-d5u4yuufpe77xdkuw2k1h9uahf.jpg
http://img.skitch.com/20100126-xrw6qd5jajytkq5u7x3kdk168s.jpg http://img.skitch.com/20100126-xrw6qd5jajytkq5u7x3kdk168s.jpg
Just in case, here's the MapViewController declaration:
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController
{}
#end
And the code to push the modal view controller:
MapViewController *mapVC = [[MapViewController alloc] init];
self.mapViewController = mapVC;
[mapVC release];
[self presentModalViewController:mapViewController animated:YES];

You are going about this the wrong way in your NIB file.
Add the MKMapView to the view of the UIViewController. You could add a navigation bar here instead of a controller if you don't wish this view to go anywhere else.
However, having the navigation controller is very handy. So, ensure that there is no navigation controller in the NIB file for your MapViewController class and then edit your code to look like this:
MapViewController *mapVC = [[MapViewController alloc] init];
self.mapViewController = mapVC;
[mapVC release];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mapViewController];
[self presentModalViewController:navController animated:YES];
[navController release];
Then you can access this controller from within your MapViewController.m file by using:
self.navigationController

Related

Adding UITabBarController to a UIViewController

My app currently has a UINavigationController and I'd like to push a UITabBarController at some point when a button is clicked. I am trying to create it on Interface Builder (as opposed to programatically).
All online tutorials show how to create a tab bar based app, which involves dragging a UITabBarController into the MainWindow.xib which is obviously not what I want.
What I did was create a UIViewController, and its nib file, dragged a UITabBarController. Now pushing that UIViewController to the navigation controller will show an empty view (its empty view). Removing the view in the view controller will crash the app. How can I tell the UIViewController to load a UITabBarController instead of its own view?
For those down-voting me: it would be decent to at least provide a comment. The question is not a poor question. The questions is asking for suggestions for how to use a UITabBarController in an unorthodox way. I tried most of the suggestions and they do not work. If you are down-voting, at least write a comment.
You can see this this may help you
Since this is how you want your app to be: - Navigation Controller - Root View Controller - Other View Controllers - Tab Bar Controller - First VC under tab - Second VC under tab - Third VC under tab - more view controllers
in your view controller where you want to pushViewController to UITabBarController use this
//create a UITabBarController object
UITabBarController *tabBarController=[[UITabBarController alloc]init];
//FirstViewController and SecondViewController are the view controllers you want on your UITabBarController (Number of view controllers can be according to your need)
FirstViewController *firstViewController=[[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *secondViewController=[[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
//adding view controllers to your tabBarController bundling them in an array
tabBarController.viewControllers=[NSArray arrayWithObjects:firstViewController,secondViewController, nil];
//navigating to the UITabBarController that you created
[self.navigationController pushViewController:tabBarController animated:YES];
This tutorial might help. It comes with an example code.
Hi just make both nav controller and tabBar Controller in app delegate.
Initially add navController to your root view..
[self.window addSubview:navigationController.view];
and whenever you want to add tab bar then remove navController and add tabBarController.
-(void)addTabBarController
{
AppDelegate *appdelegte =(AppDelegate*)[[UIApplication sharedApplication]delegate];
[[[appdelegte navigationController] view]removeFromSuperview];
[[appdelegte window]addSubview:[[appdelegte tabcontroller]view]];
[[appdelegte tabcontroller]setSelectedIndex:0];
}
If you get any problem then ask me again..
In YourView controller make IBOutlet of tabBarController
in .h file
#import <UIKit/UIKit.h>
#interface YourView : UIViewController
{
IBOutlet UITabBarController *tabBarController;
}
-(IBAction)loadTabBar:(id)sender;
#end
and in .m file
#import "YourView.h"
#import "FirstViewController.h"
#import "SecondViewController.h"
#implementation YourView
-(IBAction)loadTabBar:(id)sender
{
FirstViewController *firstView = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
SecondViewController *secondView = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:firstView, secondView, nil];
[self.navigationController pushViewController:tabBarController animated:YES];
}
#end
The tabBarController IBOutlet must be connected to the UITabBarController that on the .xib file. And that UITabBarController with two view controllers named FirstViewController, SecondViewController.
I remember doing something similar to this...
I had to create a custom UITableViewController to do this, if you are going to use UINavigationController to 'push' to it.
Doing it only in interface builder may be a bit tricky, it's been a while since I've been at it, I do recall it was a bit of a nightmare to get going correctly.
The problem was, as I believe I've mentioned somewhere, is that the XIB does not have a UIView connected to it. When the UIView is deleted in a XIB file and a UITabBarController is added, the view property of the XIB has to be connected to the UITabBarController's view. I connected it and it worked. That was the reason why I was getting a SIGTRAP.
take a uiview of tab bar controller means create an interface builder with tabs and add that tab bar uivew in your classes where ever u wanted the tab bar
for example take a tab bar uiview of 3 tabs in that uiview take the three buttons in the interface builder
for every navigation of that classu should add this uiview class
-(IBAction)firt_button_pressed:(id)sender
{
}
-(IBAction)second_button_pressed:(id)sender
{
}

iOS UInavigation bar to uitableviewcontroller not as rootviewcontroller in appdelegate

I'm loading a table view control by pressing a button in view controller
.The code in my Viewcontroller.m is
-(IBAction)go:(id)sender{
TableViewController *sec=[[TableViewController alloc]init];
sec.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:sec animated:YES];
}
Now my table view controller loads..Now i need to add a navigation bar which have title and back button which loads view controller.I also want to know how to assign action to that back button where i can load view controller
I tried out in google which all makes tableviewcontroller as root view controller where in my app rootviewcontroller is view controller..Is there a way to add that in my xib or by programmatically.
Help pls..
You can do this:
-(IBAction)go:(id)sender{
TableViewController *sec=[[TableViewController alloc]init];
UINavgationController *nav = [[UINavgationController alloc] initWithRootViewController:sec];
nav.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:nav animated:YES];
}

iPhone Navigation Back Button

I am having issues with the back button not showing up on the SettingsViewController. The navigation bar does show up when the view is pushed, but no back button.
I am creating this inside a view controller, which is not a navigation controller. Any ideas or suggestions on what is actually going on here.
- (void)viewDidLoad
{
self.title = #"Settings";
}
- (IBAction)showSettingsModal:(id)sender
{
SettingsViewController *settingsViewController = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:settingsViewController] autorelease];
[self presentModalViewController:navController animated:YES];
[settingsViewController release];
}
You are creating a new navigation stack. You will need to add your own Back button and set the action of that to a delegate method on the calling VC to dismiss it.
UPDATE:
There seems to be lots of confusion about where and how to dismiss ModalViewControllers. The wrong thing to do in most cases is to call the Dismiss method from the Modal VC itself if you are wanting the parent to act on that dismissal. Instead, use delegation. Here is a simple example:
ModalViewController.h:
#protocol ModalViewControllerDelegate
-(void)dismissMyModalVC;
#end
#interface ModalViewController : UIViewController {
id < ModalViewControllerDelegate > delegate;
}
#property (nonatomic, retain) id < ModalViewControllerDelegate > delegate;
// The rest of your class properties, methods here
ModalViewController.m
#synthesize delegate;
...
// Put in the Method you will be calling from that Back button you created
[delegate dismissMyModalVC];
CallingViewController.h:
#import "ModalViewController.h"
#interface CallingViewController : UIViewController
<ModalViewControllerDelegate>
// Rest of class here
CallingViewController.m:
ModalViewController *mvc = [[ModalViewController alloc] initWithNibName:#"ModalViewController" bundle:nil];
mvc.delegate = self
[self presentModalViewController:mvc animated:YES];
...
// The ModalViewController delegate method
-(void)dismissMyModalVC {
// Dismiss the ModalViewController that we instantiated earlier
[self dismissModalViewControllerAnimated:YES];
That way the VC gets dismissed properly from the controller that instantiated it. That delegate method can be modified to pass along objects as well (like when you are finished logging a user in, etc)
SettingsViewController does not have a back button because it is at the bottom of stack. If you want a button to dismiss the modal dialog, you will have to add it yourself.
you can try this
UIBarButtonItem * backButton = [[UIBarButtonItem alloc]initWithTitle:#"Back"style:UIBarButtonItemStylePlain target:self.navigationItem.backBarButtonItem action:#selector(dismissModalViewControllerAnimated:)];
You are presenting your new controller as modal view controller. Modal controller presents its topmost. You should:
[self.navigationController pushViewController:navController animated:YES];
to push view controller onto the stack, and then you will see Back button.
Read Apple documenation on presenting view controllers:
https://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html
EDIT Didn't see that the calling view controller is not part of the navigation controller. In that case, you will have to create back button manually, and set it as a left bar navigation item.

What is the proper way to access navbar buttons of a modal view?

I created a view in IB with a navbar and a table. On the navbar I put two buttons, cancel and done. I use this view like a modal view with:
[self presentModalViewController:controller animated:YES];
My problem is when I use:
[self.navigationItem.rightBarButtonItem setEnabled:YES];
to enable the right button. It doesn't work.
Have I to set a delegate? what code passages I have to do? It works if I create an IBOutlet for the right button and I use [doneButton setEnabled:YES], but I think this isn't the proper way.
In order to place a navigation bar on your modal view controller in interface builder (and set up bar button items that call actions in your detail view controller), you need to go through a level of indirection (your navigation bar will be in one .xib, and the details of your detail view will be in a different xib):
create a xib file containing a navigation controller object, and set its root view controller to be your detail view controller that you want to display modally with a navigation bar.
add bar button items to the detail controller's navigation bar and hook them up to IBActions in your detail view controller object.
your detail view controller will need to be in a separate .xib file
create a "loader" object that just exists to hold the navigation controller iboutlet, and set it to be the File's Owner object of that xib:
#interface Loader : NSObject
#property (nonatomic, retain) IBOutlet UINavigationController *navVC;
#end
#implementation Loader
#synthesize navVC;
- (void) dealloc
{
[navVC release];
[super dealloc];
}
#end
Your xib file containing the navigation controller will look like this:
Make sure the navigation controller object is conntected to the "Loader" object's navVC outlet, and make sure the bar button items are connected to your detail view controller's desired IBActions.
Then you present this whole thing using this code:
Loader *loader = [[[Loader alloc] init] autorelease];
[[NSBundle mainBundle] loadNibNamed:#"ModalVC" owner:loader options:nil];
[self presentModalViewController:loader.navVC animated:YES];
Delegate has nothing to do with your issue.
You probably did put navigation bar into your view directly. Thus things like self.navigationItem doesn't work. You have two choices ...
Connect your buttons to outlets in your code and access them directly.
Or remove navigation bar from your view and present your view controller in this way ...
MyViewController *vc = [[MyViewController alloc] initWith...];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:vc];
[vc release];
[self presentModalViewController:navCon animated:YES];
[navCon release];
... and now you can access left/right buttons via navigationItem.

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.