Reputation: 91
I spent so many hours with this issue, so I can't find any solution.
I open SettingsViewController from my TopBar on tap in avatar with pushViewController
method (here is problem) and from menu (not modal).
I want to dismiss this pushed ViewController when I tap on logout button.
Below is a function that I use in some VC's and works very well.
func goToSettingsView() {
let vc = SettingsViewController(nibName: "SettingsViewController", bundle: nil)
vc.modalPresentationStyle = .fullScreen
self.navigationController!.pushViewController(vc, animated: true)
for constraint in vc.view.constraints {
if constraint.identifier == "alignTopHeader" {
constraint.constant = 0
}
}
}
When I clicked logout button isn't working and when I login from (LoginViewController) this SettingsViewController is still showing, but I would go to Main Screen without any modals.
I did some ideas but not good working yet.
First idea was:
Below is my logout IBaction in my SettingsViewController:
- (void)logout {
[self dismissViewControllerAnimated:YES completion:nil];
[[UserManager shared] logoutUserWithSuccessBlock:^{
[self presentLoginViewController];
}];
}
LoginViewController is dismiss, but self is targeted for SettingsViewController?
Second idea:
I added a function declared in AppDelegate "backToRoot" in LoginViewController and call from viewWillDisappear.
[appDelegate backToRoot];
function in AppDelegate.m file
-(void)backToRoot {
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
PresentationsPickerViewController *mainvc = [[PresentationsPickerViewController alloc] init];
[self setCenterPanelWithViewController:mainvc];
}
But still not working with modal, it's work fine when SettingsViewController isn't modal.
Do you have any ideas how to hide/dismiss pushed SettingsViewController in logout action?
Upvotes: 0
Views: 1396
Reputation: 4232
I want to dismiss this pushed ViewController when I tap on logout button.
Now you don't dismiss a pushed UIViewController
. Push is a navigation style associated with a UINavigationController
. When you push a UIViewController
you need to pop it.
When we talk about dismiss, we usually mean closing a UIViewController
that is presented modally. This method means that a new UIViewController
is added on top of your previously shown UIViewController
or any class inheriting from it. This does not get added onto the navigation stack. You can only dismiss a UIViewController
if it was presented.
Now your first code block shows you pushing the SettingsViewController
and your first solution tries to dismiss it. This will not work. You need to pop it from the UINavigationController
to close it.
Next,
LoginViewController is dismiss, but self is targeted for SettingsViewController?
The method [self dismiss]...
will close the screen that is the latest presented screen on top. If you present LoginViewController
from settings, then LoginViewController
screen gets dismissed.
Also,
But still not working with modal, it's work fine when SettingsViewController isn't modal. Do you have any ideas how to hide/dismiss pushed SettingsViewController in logout action?
If your SettingsViewController
is presented then you need to dismiss it and if it is pushed, you need to pop it.
If there are situations when both the actions can occur, then on your close button action, you can check how the screen was displayed. Use this link to figure out the checks for that.
If all you want to do is go to your LoginViewController
on logging out, you can just change the root window of your application.
let window = (UIApplication.shared.delegate as? AppDelegate)?.window
window?.rootViewController = viewController //this will be your loginViewController
window?.makeKeyAndVisible()
For iOS 13:
UIApplication.shared.windows.first?.rootViewController = LoginViewController
UIApplication.shared.windows.first?.makeKeyAndVisible()
Upvotes: 1
Reputation: 124
You can simple dismiss all view controllers above the root view controller.
func logout() {
self.view.window!.rootViewController?.dismiss(animated: false, completion: nil)
}
Hope it will help. Thanks.
Upvotes: 1
Reputation: 16361
It's really simple. If you want to dismiss a pushed UIViewController
in a navigational-stack just pop it out, like this:
func logout() {
navigationController?.popViewController(animated: true)
}
Upvotes: 2