I am opening a navigationController using either directly navigation segue in storyboard or called segue from code, but still created on storyboard.
Example:
self.performSegue(withIdentifier: "addNew", sender: nil)
Which then with modal transition opens a navigationController. NC then has a few view controllers on which all have close button on them and when I click on it it closes NC using:
self.navigationController?.dismiss(animated: true, completion: nil)
But afterwards when I switch between different ViewControllers on TabbarController or open some other view with push view I get:
Unbalanced calls to begin/end appearance transitions for
And also viewWillAppear on opened view isn't called. So can anyone tell me if I'm closing the NC correctly or is there some other way to prevent the error.
EDIT1:
changed the closing call from
controller.navigationController?.dismiss(animated: true, completion: nil)
to self.navigationController?.dismiss(animated: true, completion: nil) just to make the question easier.
Also tired:
self.dismiss(animated: true, completion:nil)
EDIT2:
Is it maybe bad to open a NC from VC that is on NC that is on UITabbarController or is just simply already bad to have NavigationControllers as tabs on TabbarController?
You may need to close the controller from that controller's side:
// place this to the target controller, which handles you that modal view
self.dismiss(animated: true) {
//completion:
}
or
self.dismiss(animated: true, completion:nil)
Related
I'm totally newbie level with swift and having a question. so, I created a navigation controller for my modal and having my modal opened up from my first view controller with segue (Button2). The question is, how to get back to my first view controller from Modal View
You can use the dismiss method to dismiss a specific ViewController.
The question is how you want to dismiss the ViewController presented modally? With a button? Tap anywhere in the View? Tap on a little cross button?
For example if you have an UIButton to dismiss:
#IBAction func didTapClose(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
If the segue is "present modally", you can dismiss the view controller through this line :
dismiss(animated: true, completion: nil);
Else If the segue is "show", you can dismiss the view controller through this line :
navigationController?.popViewController(animated: true);
In this case, be sure that you embedded your ViewController to a navigationController in your storyboard. If your ViewController is not embedded to a navigationController and you have used show segue, you should use dismiss(animated: true, completion: nil) to return to previous page.
Also there is other ways to return to previous pages (e.g., unwind segue)
Good luck.
Let say I have the following VCs:
RootVC --> VC A --> VC B
I'm using present method to present view controller from RootVC to VC A then to VC B. Now I'm on VC B and I want to dismiss from VC B back to RootVC using
self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
it works but I still see VC A shows up during the dismiss process. Then, I try this method
self.presentationController?.presentedViewController.dismiss(animated: true, completion: nil)
It also works to dismiss back to root VC but I still see VC A in process.
My question is is there a way to not show VC A during the dismiss process? I already try animated: false but still get the same result. Thanks!
You need to make the change in the modalPresentationStyle to the .custom. The custom will allow you to view the presentingViewController view when the current visible controller's view is transparent.
Now when you want to go back to root view on the current presenting stack you need to call the method dismissToRootViewController(animated: completion:).
In the implementation of this method will allow all intermediate presenting view controller view to be transparent which will give you dismiss animation from VC c to RootVC.
extension UIViewController {
func dismissToRootViewController(animated: Bool, completion: (() -> Swift.Void)? = nil) {
var viewController = self.presentingViewController
while viewController?.presentingViewController != nil {
viewController?.view.alpha = 0.0
viewController = viewController?.presentingViewController
}
self.dismiss(animated: true) {
viewController?.dismiss(animated: false, completion: completion)
}
}
}
You can try to use this:
navigationController?.popToRootViewController(animated: false)
I have a problem with present UIViewController Modaly by above code
self.presentViewController(view, animated: true, completion: nil);
it doesn't work when another view present modaly such as UIAlert,its triggered by a socket packet in background and user may is performing another work and may another modal view already presented when the trigger happens.
You can not present two view controllers at the same time from the same source controller. Instead, try presenting the second view controller from the first one that was presented.
if let presented = self.presentedViewController {
presented.present(vcToPresent, animated: true, completion: nil)
}
else {
self.present(vcToPresent, animated: true, completion: nil)
}
I'm using MZFormSheetPresentationController to show as "pop-up" a ViewController2 (embedded in a Navigation controller as suggested) over a ViewController1.
My ViewController1 has a searchbar, a UISegmentedControl and a tableview:
When user clicks on the searchbar bookmark button, pop-up is shown.
I'd like to close the pop-up when user clicks on the done button and it works great using self.dismissViewControllerAnimated(true, completion: nil) method but I'm looking for more. I'd like to present again ViewController1 so tableView will reload data.
I tried with:
self.dismissViewControllerAnimated(true, completion: nil)
print("Dismissed")
//goToTickets
let next = self.storyboard?.instantiateViewControllerWithIdentifier("myTabBar") as! UITabBarController
self.presentViewController(next, animated: true, completion: nil)
but I get this error:
Warning: Attempt to present on whose view is not in the window hierarchy!
Pop-up disappears but I can't present ViewController.
How can I do?
Thanks in advance.
Edit
This is my ViewController2 with identifier "navigationFilter"
and my tabBar:
When you are in the middle of dismissing you are trying to present next ViewController, you have to wait for completion handler and then present next view controller like this:
self.dismissViewControllerAnimated(true, completion: {
let next = self.storyboard?.instantiateViewControllerWithIdentifier("myTabBar") as! UITabBarController
self.presentViewController(next, animated: true, completion: nil)
})
I am receiving this error after dismissing a multipeer connectivity window:
"Warning: Attempt to present < AudioWaves.ViewControllerJoin: 0x176cf2d0> on < AudioWaves.ViewController: 0x17594de0> whose view is not in the window hierarchy!"
Here is my code below,
func browserViewControllerDidFinish(
browserViewController: MCBrowserViewController!) {
// Called when the browser view controller is dismissed (ie the Done
// button was tapped)
let ViewControllerjoin:ViewControllerJoin = ViewControllerJoin()
self.presentViewController(ViewControllerjoin, animated: true, completion: nil)
dismissViewControllerAnimated(true, completion: nil)
}
If I put the dismiss before the presenting of the new view controller the browser dismisses however the app simply brings to a blank black screen with no error.
Chain your two calls like this:
dismissViewControllerAnimated(true, completion: {
self.presentViewController(ViewControllerjoin, animated: true, completion: nil)
})
This way chains first the dismissViewControllerAnimated and then the presentViewController, this prevent your hierarchy from strange behavior
This helped the asker to verify that his ViewController indeed is the black screen: Try changing the background color of the ViewControllerJoin to blue for example and trying again, once I saw that the default backgroundColor caused a black screen in a ViewController (this seems to help the