I have a tab bar controller. In that the first tab is a navigation controller. Lets call it controller A. I am then pushing another view controller on it. Lets call it controller B.
After that I am presenting view controller C from View controller B. Now I want to dismiss only the view controller B.
Tab Bar - A(Navigation Controller's root vc) -> Push VC -> B -> Present VC -> C
A to B is going using self.navigationController.pushViewController(animated: true, completion: nil)
B to C is going like this
let vc = CViewController()
vc.modalPresentationStyle = .fullScreen
self.present(vc,animated: true,completion: nil)
Now When I use
self.dismiss(animated: true, completion: nil) in View Controller C. It goes back to the root view controller i.e vc A. I want it to go to VC B.
After a bit of thought, I replicated what you were trying to do and figured out the problem is not with calling dismiss. It is with the way you called that View Controller in the first place. Change your "B to C" code a little bit.
Instead of:
let vc = CViewController()
vc.modalPresentationStyle = .fullScreen
self.present(vc,animated: true,completion: nil)
use:
let sb : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(identifier: "C")
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true, completion: nil)
You would have to specify the identifier of your view controller in the storyboard, (Storyboard ID)
Now when you call self.dismiss(), it should only close C.
I have tested this on my computer with Xcode 11.1.
Related
I'm trying to dismiss viewcontroller presented as modal("Present Modally") and then popViewController in navigationController. Here is my storyboard, I want to go from QRScanner VC to Monitoring VC.
Here is how I'm presenting QRScanner VC in Add Device VC:
let storyboard = UIStoryboard(name: StoryboardIDs.MainStoryboard, bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: VCIDs.QRDeviceScannerVC) as! QRDeviceScannerVC
controller.deviceName = deviceNameTxt.text
present(controller, animated: false, completion: nil)
Here is how I'm trying to go back to MonitoringVC:
self?.navigationController?.popViewController(animated:true)?.navigationController?.popViewController(animated: false)
Also tried:
self?.dismiss(animated: true, completion: {
self?.presentingVC?.navigationController?.popViewController(animated: false)
})
It always goes to the Add Device VC instead of Monitoring VC
Use an unwind segue, with the unwind target method located in the Monitoring VC. All the right stuff will just happen as if by magic.
You can try with
self?.dismiss(animated: false, completion:nil)
self?.presentingVC?.navigationController?.popViewController(animated: true)
Just check if you have reference to the navigation controller
I have two modules that I need to connect.
The authorization module, which consists of 1 screen. There is no
controller Navigation on it and it is not in its stack.
Main application. The first screen is the root for the controller
navigation.
How can I implement the transition in case of successful authorization from the authorization screen to the main application in Swift code?
My screen scheme
SOLUTION:
I use this solution for my case:
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "rootVC")
UIApplication.shared.delegate?.window??.rootViewController = vc
view.present(vc, animated: true) {
self.view.dismiss(animated: false, completion: nil)
}
Give storyboardId "nav" to the Navigation Controller and then present it on your login view controller.
if let nav = self.storyboard?.instantiateViewController(withIdentifier: "nav") {
self.present(nav, animated: true, completion: nil)
}
on your navigation Controller on storyboard add your storyboard Id, for example I have named it as navController
In your code, from you want to show as the navigation controller as present, add this line
case if presented view Controller on same storyboard
if let navController = self.storyboard?.instantiateViewController(withIdentifier: "navController") {
self.present(navController, animated : true, completion : nil)
}
case if presented view controller on different storyboard
let storyboard = UIStoryboard(name : STORYBOARD_NAME, bundle : nil)
let nav = storyboard.instantiateViewController(withIdentifier: "navController")
self.present(navController, animated : true, completion : nil)
I am building a flow like this
FirstViewController -> SecondViewController - > Tab Bar View Controller (consists of 1. ThirdViewController and 2. FourthVIewController)
I am opening Tab Bar View Controller as a pop up form the SecondViewController. However, when I run (self.dismiss(animated: true, completion: nil)) on click of a button in ThirdViewController, it goes back to the FirstViewController.
I want to go back to the SecondViewController
Adding code.
This is how I open the tab bar view controller from my SecondViewController
let popupVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "tabBarVC") as! UITabBarController
self.addChildViewController(popupVC)
popupVC.view.frame = self.view.frame
self.view.addSubview(popupVC.view)
popupVC.didMove(toParentViewController: self)
And this is how I try to close the tab bar view controller form Third View Controller
self.dismiss(animated: true, completion: nil))
You added tabBarController in secondViewController as subView. So you need to remove that tabBarController view from super view.
For that, you need a tabBarController object.
self.tabBarController?.view.removeFromSuperview()
You can use a navigation controller in your flow, so when you are in ThirdViewController use this:
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "second") as? SecondViewController {
self.navigationController?.popToViewController(vc, animated: true)
}
The below code was able to remove the tabview and take me back to the SecondViewController
self.tabBarController?.view.removeFromSuperview()
Switching to other item on UITabBar, where 0 insert index of UTTabBar item:
self.tabBarController?.selectedIndex = 0
I'm trying to make ViewController present after Modal dismiss
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let chatRoomVC = storyboard.instantiateViewController(withIdentifier: "ChatRoomVCId") as! ChatRoomVC
chatRoomVC.hidesBottomBarWhenPushed = true
chatRoomVC.passValue = passValue
self.dismiss(animated: true, completion: {
self.present(chatRoomVC, animated: true, completion: nil)
})
But it will return "whose view is not in the window hierarchy!" maybe it's present a view after the controller dismissed
Notice the self in self.present, what you are doing, is basically tell the vc that you are dismissing to present a new vc, thats wrong way to do, the correct way is tell it's PARENT vc to present a new vc, by using delegate/unwind to call the parent vc to present new vc
You are using self. It means you are dismissing the current view controller. It should be the parent view controller who will present a new view controller.
When present from "Controller_A" to "Controller_B"-> present it like given below
--- View Controller A ---
self.navigationController?.present(Controller_B, animated: true, completion: nil)
When you want to dismiss "Controller_B" and present "Controller_C" using Navigation controller
--- View Controller B ---
let presenController : UINavigationController = self.presentingViewController as! UINavigationController
presentingController.dismiss(animated: true, completion: {
presenController.pushViewController(Controller_C, animated: true)
})
I present a View Controller in the following fashion:
let vc: ChangeDateViewController = storyboard!.instantiateViewControllerWithIdentifier("changedate") as! ChangeDateViewController
let navigationController = UINavigationController(rootViewController: vc) //ensures that the top navigation bar remains in the new View Controller
self.presentViewController(navigationController, animated: true, completion: nil)
For some reason, the base presenting View Controller slides down while the new View Controller is sliding up. Although the presenting works, it does look glitchy because the sliding down reveals the black background behind the views. Is this a common occurrence, and is there anything I can do to prevent it?
Try this:
let storyboard1 = UIStoryboard(name: "Main", bundle: nil)
let conn = storyboard1.instantiateViewControllerWithIdentifier("changedate") as! LMAddaccountMainVC
self.presentViewController(conn, animated: true, completion: nil)
This might be helpful to solve you issue.