present new modal view controller then dismiss old modal view controller - objective-c

i want to dismiss my current view controller then load up a new view controller. this seems like it should work:
FieldReportViewController *fieldReport = [self.storyboard instantiateViewControllerWithIdentifier:#"fieldReportView"];
[self presentModalViewController:fieldReport animated:YES];
[self dismissModalViewControllerAnimated:NO];
i present the new modal, then dimiss the old one. but the old one doesn't actually get dismissed.
any idea how i can get this done or why this won't work?

You are not dismissing the old modal view controller....you are dismissing the new one you just presented. Try dismissing the modal view controller first.

first dismiss the old view before present the nezt one or use the actual names instead of "self"
add this code:
#import "class of the to dismiss view.h"
#class class of the to dismiss view

When you present a modal view controller, depending on which iOS version you're using, you're setting the property modalViewController or presentingViewController of the 1st modal to a second modal and adding the 2nd view controller to the view hierarchy. If you were successful in removing the first modal, the second modal would no longer be attached to any view hierarchy.
What you may want to consider is using a single view controller and just replacing the view for that modal view. I think this would give you what you want.
Alternatively, you should probably dismiss the first modal and from the previous view controller present the second modal.

Related

UIViewController auto rotate?

I setup my UIViewController in app delegate as self.window.rootViewController. For some reason I need open sign view as modal from my root view controller like:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self.window.rootViewController presentModalViewController:signViewC animated:NO];
If I change device orientation in sign view, my root view controller doesn't change orientation and I get incorrect orientation after sign view dismissed. Is it possible to change root view orientation if I changed orientation in sign view?
In my root controller I added:
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
And autorotation works if I rotate root view without modal view.
First of all, you shouldn't be presenting a modal from your app delegate. Whatever check you are doing to determine if you should present that view controller should be done in your main view controller. From there, you should call the code to present the modal, like so:
[self presentModalViewController:signViewC animated:NO]
That way, your main view controller isn't dismissed, it's only pushed down the view stack and should still respond to rotation notifications.
Try that out and let me know how it turns out.
EDIT
Take out the ModalPresentationStyle. That's what's messing you up.

Pushing a navigation controller is not supported- performing segues

I created a new navigation controller in my storyboard (not programmatically!) and set it to be "Root View Controller" to a regular UIViewController and added a button in it which says- forward to the next view controller (this second view controller is a view controller which I want that will have a back button to link to the initial view controller).
Now, whenever I try to link the button to the next view controller- "Pushing a navigation controller is not supported".
Help me please, and thanks
EDIT:
I accidentally subclassed UINavigationController, and not UIViewController in my class.
Thank you anyway.
I've tried this and have no problems, its all done in IB with no additional code required ...
Start a new project, "Single View Application" using story boards
Select storyboard and delete the views its produced.
Drag on a new Navigation Controller (it will bring a table view with it)
Delete the table and the table view controller, so you are just left with the Navigation Controller
Drag on a normal view controller
Right Click and drag from the Navigation controller to the new View and choose "Relationship - Root View Controller"
Drag a "Bar Button Item" on to the Navbar which should be visible on the top of your ViewController, you can rename this Forward if you wish.
Now drag on another view controller which is the one your "Forward" button will push in to view.
Right Click and drag from the bar button to the 2nd View Controller, and choose "Push"
Run the project and you will get a Single view with a Navbar and your button, clicking your button will Push the other view and give you a Back Button to return to the first View Controller. I'll try and post a picture of my storyboard if it helps.
Plasma
I had the same trouble. I wanted to have a navigation controller on each storyboard, so that each could run independently, be individually debugged, and so that the look would be right with the navigation bar.
Using other approaches, I found the UINavigationController would be retained from the original storyboard -- which I didn't want -- or I'd get errors.
Using the AppDelegate in your view controller to set the rootViewController worked for me (borrowing segue naming conventions from Segue to another storyboard?):
- (void)showStartupNavigationController {
NSLog(#"-- Loading storyboard --");
//Get the storyboard from the main bundle.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Startup" bundle:nil];
//The navigation controller, not the view controller, is marked as the initial scene.
UINavigationController *theInitialViewController = [storyBoard instantiateInitialViewController];
NSLog(#"-- Loading storyboard -- Nav controller: %#", theInitialViewController);
//Remove the current navigation controller.
[self.navigationController.view removeFromSuperview];
UIWindow *window = [(AppDelegate *)[[UIApplication sharedApplication] delegate] window];
window.rootViewController = theInitialViewController;
To swap views Programatically you would need to select the segue and give it an Identifier like "PushView" then call it like this ....
[self performSegueWithIdentifier:#"PushView" sender:self];
That will programatically do the same as clicking the forward button. I've created you an example project with the code discussed above. Has an -(IBAction) with code in you can use for programatially changing the view.
PushView.zip
I also wanted to do this, present a screen (that had an embedded navigation controller) when the user pushes a button.
At my first attempt, I connected the segue from the button in the fist screen to the Navigation Controller, and the app was crashing with this error "Pushing a navigation controller is not supported".
This is the solution I found:
Select the segue from the button in the first screen to the navigation controller.
If it had an identifier, copy its name. Then delete that segue.
Then create a new segue by CTRL-clicking the button in the first view controller and dragging to the VIEW CONTROLLER YOU WANT TO PRESENT (not to the Navigation Controller that is pointing at it), and select Push in the small pop up window.
Then click the icon in the middle of the segue and paste the name you copied in the first step as an identifier for it.
IB is going to give you a warning "Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:." Don't worry, it works perfectly.
If you want to customize the string that is shown as the Back button to return, you can add this line in the viewDidLoad method OF THE VIEW CONTROLLER THAT IS BEING SHOWED AFTER THE BUTTON IS PRESSED, that is the Child view controller.
(replace "Settings" with the name you need)
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.topItem.title = #"Settings";
...
}

PresentModalViewController removes subviews

This is driving me crazy! I have a UIViewController with 1 button.
The VC loads and I place a view into the VC:
[self.view addSubview:myView]
When you press the button, it presents a Modal:
[self presentModalViewController:self.newVC animated:YES];
When that modal appears, it removes the subview I have added. Is there any way to prevent this from happening?
Thanks!
When you present the modal view controller its view pops up and covers the existing view until you dismiss the modal view controller.
Until you do this the original view (and your button) will remain hidden behind it.

Modal view using UIModalPresentationFormSheet doesn't autorotate when it's covered by another modal view using UIModalPresentationFullScreen

I have three view controllers: MainViewController, FirstModalViewController and SecondModalViewController. All of them have implemented shouldAutorotateToInterfaceOrientation:.
In MainViewController, I present a FirstModalViewController using presentModalViewController:animated: with modal style of UIModalPresentationFormSheet. Then, in FirstModalViewController, I present a SecondModalViewController using the same method but with modal style of UIModalPresentationFullScreen.
The problem is that after I rotate the device and then dismiss the SecondModalViewController, I notice the FirstModalViewController does not autorotate, but the MainViewController autorotate.
Why FirstModalViewController does not autorotate when it is covered by SecondModalViewController?

how to load UITabBarController?

I have a code that currently loads a NIB file like below :
Login *monLogin = [[[Login alloc] init] autorelease];
[self presentModalViewController:monLogin animated:YES];
but the app is TabBar App (xcode template) and is suppose to also load the bottom menu.
how can I load this NIB file with the UITabBarController included?
my answer to your other question might help. But now I'm a little confused about what you're attempting to do. Let me know and I can help you further.
The modal view will not include the TabBar because a TabBar owns the view controllers represented by each tab. Why do you want the TabBar included in the login view? If you really want a TabBar in your modal view, then you'll need to put your 'log in' view controller inside a TabBar view controller, and then present the TabBar view controller modally.
However, I'd recommend that you have the TabBar in the main part of your app, and present the 'log in' view modally without a TabBar included. Once the user is finished logging in, you can dismiss the 'log in' view, which returns the user to the main part of your app.
To dismiss the modal view controller, set up a delegate system (look through the utility app template to see how this works). If setting up your own delegate protocol is too difficult at the moment, then you can use a workaround in the mean time. In your 'log in' view controller code, after the user has logged in successfully, you can send a message to your parent view controller (the one that presented the modal view) to dismiss it's modal view (your 'log in' view).
[self.parentViewController dismissModalViewControllerAnimated:YES];
This is bad form though. Once you're up to it you should use a delegate callback to have the parent view controller dismiss the modal view.