i am using a tabbarcontroller in my app and also want to use a loginview.
I have an LoginController which handles the loginprocedure.
I am presenting the loginView modally.
[self.tabbarcontroller presentModalViewController:loginView animated:NO];
And on other point i am dismissing it(after login is successfull):
[self dismissModalViewControllerAnimated:YES];
After dismiss i have just a blank screen. Thats the blank window in my MainWindow.xib, i have checked it with a testlabel.
Throubles with that. No ideas how to solve this issue.
Two things:
The self.tabbarcontroller should not be instantiating the modal view. It should be the initial view controller that the tabbar controller controls. In the initialization of that view controller, you check for a login session and present the login VC.
Make sure you are dismissing that modal VC you created in the method that presented it. You should have a delegate method for your Login VC (something like loginFinished) that is handled in the VC that presented it.
Related
The initial view controller on my app is a UITabBarController that displays for logged in users.
For new users, however, my app delegate will point them to a login/registration view controller first:
// New user, show login
self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
When the user has completed the login/registration, I then send the user to the tabbar as such:
// Login done, go to main view
[self performSegueWithIdentifier:#"userLoginToMainSeg" sender:self];
However, doing it this way, the LoginViewController is not released (dealloc is not called).
Can someone explain the error in my logic here?
Your modal segue is basically doing:
[loginViewController presentViewController:mainViewController animated:YES completion: ...];
What this means is that mainViewController becomes loginViewControllers presentedViewController:
loginViewController.presentedViewController == mainViewController
mainViewController.presentingViewController == loginViewController
When you're presenting a view controller, the presenting view controller remains in the view controller hierarchy, so that you can later navigate back by calling:
[loginViewController dismissViewControllerAnimated: ...];
So it's perfectly normal that loginViewController is not released, since it's still the window's rootViewController. It's only that loginViewController is obstructed by the presented mainViewController.
If you want to eradicate loginViewController you can set window.rootViewController directly, but that wouldn't animate the transition. You can achieve animation by messing around the view controllers' views, but it's kind of outside the officially sanctioned territory...
IMO the cleanest solution would be to implement a basic container view controller that would be your window's rootViewController, and that could orchestrate the transition between loginViewController and mainViewController by animating their views, and then throwing away loginViewController. It would be kind of a primitive navigation controller without a navigation bar and a navigation stack – just swapping the current view controller with the new one, and throwing away the former.
Setting:
The first view controller for my app is PostsViewController. In viewDidLoad I check if the user is logged in, and if not I preset SignupVC modally. There is an option to login instead of signup of course, and I want to replace the signup VC with a login VC.
I tried making a "show detail (replace)" segue from signup to login VC, but that seemed to present login modal on top of signup VC. The problem with it is after the user is logged in, I have two modals to close, and it seems tricky to close both of them at the same time. Ideally, I want to replace the signup VC with the login VC and only close one modal.
Q1. How come the show detail segue works like present modally segue when applied to a modal view controller?
Q2. How can I replace the SignUp View controller with a login View controller?
Right so after rereading your question and your comment it's clear what you're trying to do here.
Q1: Because you can only present a viewController modally on parent / child views that are modally presented. You cannot push a new viewController onto a modally presented viewController. In order to push a viewController you need a UINavigationController in the view hierarchy (Normally the parent / root view)
Q2: You'll need to present it modally from the signupVC.
Example:
//Somewhere in SingupVC
[self presentViewController:LoginVC animated:YES completion:nil];
Edit
To answer your question in the comments:
No there really isn't a way to dismiss both VC's at the same time.
However there are a couple of ways to do it almost:
You can set a boolean flag on SingupVC that LoginVC was presented. That way, when viewWill/Did appear is called on singupVC and the boolean flag is set to YES you can call: [self dismissViewControllerAnimated:NO completion:nil];
And that way both VCs are dismissed. One when the user dismisses LoginVC via the back button and SingupVC via a if statement in one of the view life cycle methods (if loginVCPresent) dismiss view, type of thing.
I'm developing an iPad App using storyboards. In this app when the user click on "preferences" appear a modal View. One button of this view send the user to another View Controller (but this view has an action bar to go back to his root view controller), but when user taps the action bar back button nothing happen (it's called navigationController popViewControllerAnimated), the user continue in the same view.
Can anyone help me??
Thanks.
UPDATE:
The code to handle the back button:
- (IBAction)btnBackTapped:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
I'm using Segue (from storyboard) to call this View Controller:
When the user click on "Meus Favoritos"
They will be redirect to this page:
The segue is with a Modal (from image one to two)...
When you are presenting a View Controller modally, it is likely not within a Navigation Controller, so probably the reference to navigationController in your code is nil, can you check that?
If you are presenting your View Controller modally this will work instead
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
However, if you actually want to use a Navigation Controller, you should embed the View Controller that is presenting the Preferences View Controller in a Navigation Controller and present the Preferences View Controller with a show segue instead of a modal one.
I have a sign in VC that pushes a sign up VC; both are under a Navigation Controller. From the sign up VC I call modaling a UITabBar VC with the whole application content. Inside the UITabBar VC I have another VC with a Sign Out method. My question is: how is the correct way to go back to Sign In VC? In this scenario, if I dismiss the UITabBar VC I return to the sign up VC.
I have drawn a diagram that describes the scenario:
Any help will be appreciated.
Thanks,
Marcos
You can change the state of the UINavigationController which is presenting the modal view before dismissing it. For instance calling
[(UINavigationController *)self.presentingViewController popToRootViewControllerAnimated:NO]
from the modal view controller, will result in your underlying UINavigationController to get back to its root view controller, which - in your specific scenario - will be the Sign In VC, so when you dismiss the modal view, the underlying view controller will be whatever you desire.
Below is a hierarchy of my navigation controller
MainViewController
|
|
DetailViewController
Then I do the following on DetailViewController
[self presentViewController:reminderController animated:YES completion:nil];
After navigating to ReminderViewController, at some points I do
[self dismissViewControllerAnimated:YES completion:nil];
However, it brings me back to MainViewController instead of DetailViewController
That is weird. Any thoughts about this issue...
EDITED :
The reason I do presentViewController: reminderController animated: completion: on DetailViewController because reminderController is used to send a reminder. Just like goole app or other apps, when sending sth , we are using presentViewController.
Here is a sample of the documentation regarding the UIViewController class:
The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, it automatically forwards the message to the presenting view controller.
If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
Thus, I think you should first use a segue to push your DetailViewController, and then present the reminderController modally, which you'll be later able to dismiss using dismissViewControllerAnimated:completion: without dismissing DetailViewController.
Instead of using dismissViewController:animated: use
[self.navigationController popViewControllerAnimated:YES];
dismissViewController:animated removes all the UIViewControllers in it.
You will save you a lot of trouble if you read the UIViewController and UINavigationController references. Twice ;)
See this post for more details.