My App uses a modal view when users add a new foo. The user selects a foo type using this modal view. Depending on what type is selected, the user needs to be asked for more information.
I'd like to use another modal view to ask for this extra information. I've tried to create the new modal view like the first one (which works great) and it leads to stack overflow/“Loading Stack Frames” error in Xcode.
Am I going about this in completely the wrong way i.e. is this just a really bad idea? Should I rethink the UI itself?
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:addController];
[self presentModalViewController:navigationController animated:YES];
Fixed. I got the behavior I wanted by pushing the second view controller to the first view controller's UINavigationController.
creation of 1st modal view
FooAddController *addController = [FooAddController alloc]
initWithNibName:#"FooAddController" bundle:nil];
addController.delegate = self;
addController.foo = newFoo;
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:addController];
[self presentModalViewController:navigationController animated:YES];
[addController release];
creation of 2nd modal view (in FooAddController)
FooAddSizeViewController *addSizeController = [[FooAddSizeViewController alloc]
initWithNibName:#"FooAddSizeViewController" bundle:nil];
addSizeController.delegate = self;
addSizeController.foo = self.foo;
[self.navigationController pushViewController:addSizeController animated:YES];
[addSizeController release];
You need to take care on which instance you invoke the presentModalViewController when you deal with several levels of modal controllers.
Let's suppose you have :
[myControllerA presentModalViewController:myControllerB animated:YES];
Next time you want to display a modal controller while B has the focus, you should invoke
[myControllerB presentModalViewController:myControllerC animated:YES];
in order to get the parent controller properly set.
The hierarchy of controllers is then A-> B -> C
Did you try calling presentModalViewController on self.navigationControllerin both steps?
Related
I have the following code in application didFinishLaunchingWithOptions where I want to present a modal view controller for user login.
LoginViewController_iPhone *loginViewController=[[LoginViewController_iPhone alloc]initWithNibName:#"LoginViewController_iPhone" bundle:nil];
UINavigationController *loginNavigationController=[[UINavigationController alloc]initWithRootViewController:loginViewController];
loginNavigationController.modalPresentationStyle=UIModalPresentationFullScreen;
[self.window.rootViewController presentModalViewController:loginNavigationController animated:NO];
[loginViewController release];
[loginNavigationController release];
However, all I get is a blank white screen. If I substitute the following
self.window.rootViewController=loginNavigationController;
the login screen displays correctly. There is no other view controller assigned to the rootViewController property as the app is just starting. Do I need another view controller assigned to get this to work?
Yes. you need to assign something to the window's rootViewController property in order to call its method presentModalViewController.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:LoginViewController];
navController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navController animated:NO];
You can set this up in the viewDidLoad of the view that would load up first as soon as the app starts. So, as soon as login is successful, you can pop it off, and you will have the loaded view ready.
I want to know the differences between the
[self presentModalViewController:controller animated:YES];
and
[self.navigationController pushViewController:controller animated:YES];
I have used both but still do not know or noticed the difference. when should use one of them ?
Thanks..
Basic difference :
pushViewController only works in navigation controllers
presentModalViewController works for all view controllers
navigationController is the instance of your UINavigationController, which is used by all the controller in your navigation stack (UIViewController).
Presenting a modal view is presenting a view on top of another view. You perform those typically for "tasks" that need to be started and completed in a self contained way. Read further on modal views on the apple developer guides.
Pushing a view on to the navigation controller is different where there is a logical need for navigation in the app. Say a drill down table as in the setting app of the iDevices, where there are main settings then you drill down to sub settings etc.
Whatever your questions are, if they are conceptual and generic as this I'd strongly advise you to google up "X programming guide" which will take you to the proper Apple programming guide :) X = view controller in your case
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html
if base class has it's own NavigationController then you can write:
[self.navigationController pushViewController:objMyViewController animated:YES];
if your base class has only UIViewController then use:
MyViewController * objMyViewController = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:objMyViewController];
navController.navigationItem.leftBarButtonItem = nil; // make nil if you want
// to use it in next View
[self presentModalViewController:navController animated:YES];
now, MyViewController has navigation so you can -- Push -- another viewController by writing function as bellow in MyViewController.
-(IBAction)btnNext_click {
SecondViewController * objSecondViewController = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:objSecondViewController animated:YES];
}
I've read the post : Pop-up modal with UITableView on iPhone
and I don't understand the following part of the answer (as I can't comment the original post, I create this new question) :
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:optionViewController];
Why allocate a new controller as the window from where the new optionController is called may already have one ?
What if I just write :
OptionViewController* optionViewController = [[OptionViewController alloc] initWithNibName:#"OptionView" bundle:nil];
[self.navigationController presentModalViewController:optionViewController animated:YES];
It seems to work...
If I have a list, that goes to a detail View, from where I switch to a modify view, and then from where I call this option window, what would be the code to use to call this optionWindow ? This one ? Any other one ? I really have a problem dealing with UINavigationController between screens... (where should be defined the first one, what should be passed between screens, when may I create a new one, ...)
Modal views don't use the UINavigationController of their parent. This means that if you need a "stack" of new view controllers in your modal view then you'll need to add your own. On the other hand, if you don't need the functionality of a navigation controller in your modal view then there's no reason to add one.
Here are sone more details of how I did it in two of my apps:
My root view controller has a UINavigationController. I open a modal view using this code:
TwitterPostViewController* vc = [[TwitterPostViewController alloc] init];
[viewc presentModalViewController:vc animated:YES];
[vc release];
The modal view is then dismissed using this code:
[self dismissModalViewControllerAnimated:YES];
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];
I am creating a Navigation based iPhone application.
In that I have called a UiViewController using presentModalViewController. After that, the ViewController becomes visible. From that ViewController I need to call another ViewController using the sample presentModalViewController. Is this possible or not?
What do you mean by "call another uiviewcontroller"? (It really helps if you can be more detailed in your question.) If you mean, "slide in another view controller", then:
MyNewViewController *myNewViewController = [[MyNewViewController alloc] initWithNibName:#"MyNewViewController" bundle:nil];
[navigationController pushViewController:myNewViewController animated:YES];
[myNewViewController release];
...where:
MyNewViewController is the new view controller class that you want to slide in (the above code assumes you have an XIB file for the view controller class).
navigationController points to the current navigation controller. You'll have to replace it with something like [self navigationController], depending where you are in the view hierarchy.
U might be using following line to present a view controller.
//assume name of viewController which u want to present is "myViewController"
[self.navigationController presentModalViewController:myViewController animated:YES]
If you want to push an other ViewController or present an other ViewController then u will need to replace above line with following lines.
//[self.navigationController presentModalViewController:myViewController animated:YES];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myViewController];
navigationController.navigationBarHidden = YES; //if u want to show navigation bar then remove this line
[self presentModalViewController:navigationController animated:YES];
After using above code you can present or push other view controllers within presented view controller.
Hope it will solve your problem :)