Showing a modal view controller from a tab bar app - iphone

First, I would like to warn that I am a complete newbie into iPhone coding...
I need to show up a viewcontroller from a library, I know that it is modal. I have a tab bar app (created with the default XCode template). I need to show that viewcontroller, there are no problem if it hides the tabbar itself... But I am quite clueless, I don't know even what to search, or what to read...

You can call presentModalViewController:animated: to display another UIViewController modally.
EDIT: If you want to display your modal view in response to a button touch (for example), you would display it like this:
- (IBAction)buttonTouched:(id)sender
{
ModalViewController* controller = [[ModalViewController alloc] init];
[self presentModalViewController:controller animated:YES];
[controller release];
}
Then when you want to dismiss the modal controller, call dismissModalViewControllerAnimated:. This can be called either on your main view controller, or the modal one.

I don't know even what to search, or
what to read...
View Controller Programming Guide is a good place to start to help you understand view controllers (including modal ones). If that's confusing, get a bigger picture with iOS Application Programming Guide or start at the very beginning.

You can call modal view as
YourViewController *yvc = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:YES]
[self presentModalViewController:yvc animated:YES];
You can call it in the IBAction method in case you want to call it on any control event like Button Click
-(IBAction)buttonClicked:(id)sender
{
YourViewController *yvc = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:YES]
[self presentModalViewController:yvc animated:YES];
}
You can call it using self.
Hope this helps you.
If you have more doubts on this then you can ask me.

Related

UIViewController displayed behind current view when presented modally

On iOS 5, when I try to present any view controller from another one, using presentModalViewController, the modal view is presented behind the current view.
Since it works fine on iOS 4 and knowing that presentModalViewController has been deprecated in iOS 5, I tried using presentViewController with no luck.
This is the first time I encounter this issue, any ideas on what could lead to this weird behavior?
I believe the issue is that you have not set a proper modal presentation style.
http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/c_ref/UIModalPresentationStyle
This sample should trigger a full screen modal over top of your existing view controller.
[self setModalPresentationStyle:UIModalPresentationFullScreen];
ViewController2 *vc = [[ViewController2 alloc] initWithNibName:#"ViewController2" bundle:nil];
[self presentViewController:vc animated:YES completion:NULL];
Not sure if you're using a button to present the view controller, but this should work if you are. Create a new function in your view controller like the one below. This instantiates your view and a navigation controller in your view so it can be dismissed afterwards.
- (void)buttonPressed {
UIViewController *yourViewController = [[UIViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navigationController = [[UINavigationController] alloc] initWithRootViewController:yourViewController];
[self presentModalViewController:navigationController animated:YES];
}
And then in viewDidLoad you'd have something like this (if you were presenting it from a button). The code below is for a UIBarButtonItem, but other buttons should work in a similar manner. Just make sure you set the action parameter to #selector(buttonPressed), or whatever the name of the function you want called when the button is pressed.
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] init]
target:self
action:#selector(buttonPressed)];
I have finally found the issue. For some awkward reasons, the rootViewController of the root window wasn't set properly, leading to strange behaviors with modal views.
What is the more puzzling is that it worked fine on iOS 4 so far and failed on iOS 5. I believe I'm still missing the true reasons leading to such trouble, but correctly setting the rootViewController in AppDelegate solved the problem.

Best way to switch View Controller in iOS

I have 2 view controllers in my project. Inside View Controller1 I want to switch to View Controller 2 by press of a button. Currently I do this
- (IBAction)startController2:(id)sender {
viewController1 vc2 = [[viewController2 alloc] init];
self.view = vc2.view;
}
This seems to work fine, but there is a big delay (4 secs) between the button press and second view controller appears. If I call the viewController2 directly from the AppDelegate things load faster. What am I doing wrong here. Any help is greatly appreciated.
Several things to consider.
Part 1: "What am I doing wrong here"?
You definitely didn't mean to do self.view = vc2.view. You just put one view controller in charge of another view controller's view. What you probably mean to say was [self.view addSubview:vc2.view]. This alone might fix your problem, BUT...
Don't actually use that solution. Even though it's almost directly from the samples in some popular iPhone programming books, it's a bad idea. Read "Abusing UIViewControllers" to understand why.
Part 2: What you should be doing
It's all in the chapter "Presenting View Controllers from Other View Controllers".
It'll come down to either:
a UINavigationController, (see the excellent Apple guide to them here) and then you simply [navigationController pushViewController:vc2]
a "manually managed" stack of modal view controllers, as andoabhay suggests
explicitly adding a VC as child of another, as jason suggests
You should consider using UINavigationController to switch view controllers. If your building target is iOS 5.0+, you can also use the new controller container concept: [mainViewController addChildViewController:childViewController].
Use presentModalViewController as follows
[self presentModalViewController:vc2 animated:YES completion:^(void){}];
and in the viewController1 use
[self dismissModalViewControllerAnimated:YES completion:^(void){}];
where ever you want to go back to previous controller.
[aController presentViewController:bController animated:NO completion:nil];
[bController presentViewController:cController animated:NO completion:nil];
when you want dismiss cController, you can do like this
[aController dismissViewControllerAnimated:NO completion:nil];
this is the flow chart.
aController → bController → cController
↑___________________________↓
You should use UINavigationController to switch view controllers.
You are on View1 and add the following code on button click method.
View2 *View2Controller = [[View2 alloc] initWithNibName:#"View2" bundle:nil];
[self.navigationController pushViewController:view2Controller animated:YES];

Kill View and back to rootViewController

I am new to IOS, sorry in advance if I ask a stupid question.
I use UITabBarController and navigationController to control view.
At my last view, I would like to have a button when the button is pressed, view will return to rootViewController which I set by MainWindow.xib file and kill any process which run in app background.
this is my code in the last view before I want to back to rootViewController:
-(IBAction)doneButtonPressed:(id)sender{
JourneyIndexViewController *journeyIndexVC = [[JourneyIndexViewController alloc] initWithNibName:#"JourneyIndexViewController" bundle:nil];
[journeyIndexVC setDistanceLabelValue:self.distanceLabelValue];
[self.navigationController pushViewController:journeyIndexVC animated:YES];
[journeyIndexVC release];
[self dismissModalViewControllerAnimated:YES];
}
JourneyIndexViewController is the rootViewController that I set in MainWindow.xib.
Thank you very much for your advance support.
try
[self.navigationController popToRootViewControllerAnimated:YES];
You should take a look at this: UINavigationController Class Reference for better understanding
I am making a few assumptions here, but if JourneyIndexRootViewController is your rootViewController and is created in IB (in a nib), you do not need to re-crete it when pushing the button. It sounds like you simply need to remove the UINavigationController that you added on top of the rootViewController.
Try this. This should pop you back to the Previous View Controller.
[self.navigationController popViewControllerAnimated:NO];
Hope this helps

Add view to a navigation controller on app launch

I have an app that has a UITabBarController, one of the tabs of which is configured for a navigation controller.
Based on certain logic I need to attach a different root view to the navigation controller inside the tab at application launch time.
This is easily done in interface builder however, because I need to figure out what view to attach at launch time interface builder is not much use to me in this situation.
I'm guessing I will need to perform this in the applicationDidFinishLaunching method in my app delegate class by somehow getting the tab I'm interested in, and pushing the view onto it's navigation controller?
How would I go about this?
Thanks.
You're on the right track. In your app delegate's applicationDidFinishLaunching method, you need to look at whatever your condition is and pick the right thing to set as the UINavigationController's root view controller.
I'm guessing this is a login screen or something? And if you have a cached login from an earlier session you don't show it again? Is that it?
If you take a look at that method in your application delegate, you'll see where the default root view controller is getting instantiated and pushed into the nav controller. Just duplicate that code inside an if() statement. I've done this, it's straightforward.
So what I did in my applicationDidFinishLaunching method was:
// get the array of tabs
NSArray *tabBarArray = tabBarController.viewControllers;
// in my case the navigation controller I'm interested in is in the 4th tab
UINavigationController *navigationController = [tabBarArray objectAtIndex:4];
if(someLogic == true) {
ViewController1 *viewController1 = [[viewController1 alloc] initWithNibName:#"View1" bundle:nil];
[navigationController pushViewController:viewController1 animated:NO];
[viewController1 release];
}
else {
ViewController2 *viewController2 = [[viewController2 alloc] initWithNibName:#"View2" bundle:nil];
[navigationController pushViewController:viewController2 animated:NO];
[viewController2 release];
}
Everything working well.

Navigation controller crashing on second time

I am using one navigation controller in my application. I am having one main view (with main view controller) and few options views. Options views are viewed by navigation controller when a button clicked on main view's toolbar.
Everything works as expected for first time. When I came back to main view from navigation controller and tries again to go to option view (i.e. navigation controller) my application crashes.
Following is my code,
//Jump to navigation controller from main view controller
optionsViewController *optionsView = [[optionsViewController alloc] initWithNibName:#"optionsView" bundle:nil];
navControllerSettings = [[UINavigationController alloc] initWithRootViewController:(UIViewController *) optionsView];
[self presentModalViewController:self.navControllerSettings animated:YES];
//Code to go back to main view from navigation controller
[self.navigationController dismissModalViewControllerAnimated:YES];
What is correct mechanism to handle navigation controller? Do I need to release/dealloc the navigation controller or options view?
Sample code will help better.
Your navigation controller only gets set up once, then you push and pop other views from its stack.
UINavigationController *navController = [[UINavigationController alloc] init];
UIViewController *yourMainViewController = [[yourMainViewControllerClass alloc] init];
// when you are ready to go to your options view
optionsViewController *optionsView = [[optionsViewController alloc] initWithNibName:#"optionsView" bundle:nil];
[navController pushViewController:optionsViewController animated:YES];
// the back button and the pop from the stack when it is hit is handled auto-magically for you
Thanks for the reply.
But my application architecture is, I am having one main view on which I display few things and having toolbar. Toolbar contains one button, after clicked on that this navigation controller gets created and displayed on the screen.
using back button I came on the main view. But then after I could not go on the navigation again as it is crashing while executing following line
[self presentModalViewController:self.navControllerSettings animated:YES];
What might be the problem here?
Vishal N
I had a similar problem to this with it crashing in presentModalViewController: on second attempt. The problem was caused by calling [self becomeFirstResponder] in viewDidAppear: inside the first UIViewController that I presented, but I failed to call [self resignFirstResponder] in viewWillDisappear:.