I'm using this type of transition to UIViewcontroller:
self.navigationController?.popToViewController(MainVC(), animated: false)
And in result i want to receive the MainVC with all subviews... but i receive only empty main View without any subviews. What i did wrong?
Update:
I have the transition to MainVC, but it's empty, only initial View, without all subviews. What is the reason?
You should pass object of MainVC()
like below
let objOfMainVC = MainVC()
self.navigationController?.popToViewController(objOfMainVC, animated: false)
If you are using storyboard then
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let main = storyBoard.instantiateViewController(withIdentifier: "MainVC") as! MainVC // set withIdentifier to your identifier that was set in your storyboard.
self.navigationController?.pushViewController(main, animated: false)
You need the reference of MainVC. You can't just create a new instance of MainVC()
if let viewControllers = self.navigationController?.viewControllers {
for vc in viewControllers {
if let _ = vc as? MainVC {
self.navigationController?.popToViewController(vc, animated: true)
break
}
}
}
Or if your MainVC is root view controller of navigation controller.
self.navigationController?.popToRootViewController(animated: true)
Related
I'm in trouble, after that I'm moving from View Controller to a second View Controller and then switching back to the View Controller and clicking on the UI Image Picker it's not appearing and bringing me back to the second View Controller. On the debugger it's appearing:
Attempt to present on whose view is not in the window hierarchy!
I'm really becoming crazy. My code that is bringing me back from second View Controller to the first View Controller is inside a button and it's below:
#IBAction func profileButton(_ sender: Any) {
let webVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as! ViewController
webVC.profileLink = linkProfilo
self.present(webVC, animated: false, completion: nil)
}
in second view controller add this variable:
var firstVC: ViewController?
and this setter function to set it
setup(firstVC: ViewController) {
self.firstVC = firstVC
}
in the first view controller, when presenting second view controller pass in a reference to self (first view controller)by calling the setup function
let secondVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as! ViewController
secondVC.setup(firstVC: self)
self.present(secondVC, animated: false, completion: nil)
now when button is clicked in secondVC,
guard let first = self.firstVC else {return}
first.profileLink = linkProfilo
self.dismiss(animated: false, completion: nil)
I finally found the way for fix all of this:
#IBAction func profileButton(_ sender: Any) {
if let webVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as? ViewController {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
webVC.profileLink = linkProfilo
dismiss(animated: false, completion: nil)
appDelegate.window?.rootViewController!.present(webVC, animated: false, completion: nil)
}
}
it's enough to add the appDelegate sharing method and dismiss before to present the webVC for share the data in the right way and don't cause problems on the first view when presented.
I would like to jump from a viewController to the first viewController related to Tab Bar Controller through code.
The tabBarController Scene has storyboard id tabView.
I'm working on this way:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: UITabBarController!
storyboard.instantiateViewController(withIdentifier: "tabView")
vc=storyboard.instantiateViewController(withIdentifier: "tabView") as! UITabBarController
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
self.present(vc as! UIViewController, animated: true, completion: nil)
}
But it loads only the first viewController (out of 5) without the tab bar related to. How can I solve it?
Oh, this code looks so wrong.
In your storyboard give and "tabView" ID to the TabBarController, not the ViewController inside it.
Why you are double instantiating ViewController? just do it once and assign it to the vc variable.
Why you've created delay before presenting the VC? It's some sort of workaround of something?
Working code:
let vc = storyboard.instantiateViewController(withIdentifier: "tabView") as! UITabBarController
self.present(vc, animated: true)
Use
(1)if you want to navigate from Appdelegate
let appDelegate = UIApplication.sharedApplication.delegate as! AppDelegate
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let tabBar = mainStoryboard.instantiateViewControllerWithIdentifier("TabBarController") as! TabBarController
appDelegate.window?.rootViewController = tabBar
appDelegate.window?.makeKeyAndVisible()
(2)if you want to navigate from viewcontroller which has root of navigation
self.navigationController?.pushViewController(tabBar, animated: true)
I have a UITabBarController and all my other view controllers are connected to it. Now I want to show one my controller as:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ViewController = storyboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
but when I tried to:
let rootViewController = self.window?.rootViewController as! UINavigationController
rootViewController.pushViewController(vc, animated: true)
it gave me the next error:
Could not cast value of type 'UITabBarController' (0x1a899b818) to 'UINavigationController'
Later I've tried to do:
let rootViewController = self.window?.rootViewController as! UITabBarController
but in this case I get
UITabBar has no member pushViewController
How can I show/push my ViewController so it will appear with UINavigationBar and inside of UITabBar?
You need to place each of your view controllers inside a navigation controller.
E.g. currently you have a TabBarViewController
and two view controllers:
ViewControllerA
ViewControllerB
What you need to do is to embed each of them inside a navigation controller so you would have:
UINavigationController -> ViewControllerA
UINavigationController -> ViewControllerB
In order to push a new controller you would do:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ViewController = storyboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
let navViewController = myTabBar.selectedViewController as? UINavigationController
navViewController?.pushViewController(vc, animated: true)
Could not cast value of type 'UITabBarController' (0x1a899b818) to 'UINavigationController'
Your root view controller is of type UITabBarController.
Therefore you have to use the appropriate methods of this class and not UINavigationController.
To set view controllers use either
var viewControllers: [UIViewController]? or
func setViewControllers([UIViewController]?, animated: Bool).
To have a navigation bar you have to instantiate a UINavigationController and add your view controller to this navigation controller.
Then add your navigation controller to your UITabBarController with via one of the above options.
If your class is UITabBarController
You can add this:
private func showViewController() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let vc = storyboard.instantiateViewController(withIdentifier: "queueTableViewController") as? QueueTableViewController else { return }
let navVC = self.selectedViewController as? UINavigationController
navVC?.pushViewController(vc, animated: true)
}
This will allow you to go to any VC
The second solution is something like this.
Here You will show the last VC and from there push some VC.
guard let tabCount = viewControllers?.count, tabCount > 1 else { return }
selectedIndex = tabCount - 1
if let navigationController = viewControllers?[selectedIndex] as? UINavigationController {
if let accountVC = navigationController.visibleViewController as? FirstViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let vc = storyboard.instantiateViewController(withIdentifier: "someViewController") as? SomeViewController else { return }
accountVC.navigationController?.pushViewController(vc, animated: true)
}
}
let customerStoryboard = UIStoryboard(name: "Customer", bundle: nil) //First(Current) storyboard
let agentStoryboard = UIStoryboard(name: "Agent", bundle: nil) //Second storyboard
var otherVC = UIViewController! // ViewController reference
otherVC = agentStoryboard.instantiateViewControllerWithIdentifier("AgentProfile")
The last statement is not executing or showing results, is anything else required to do other than this?
You only instantiate view controller. To present it you should use presentViewController method
someVC.presentViewController(otherVC, animated: true, completion: nil)
Use this code to show the second view controller.
let otherVC : AnyObject! = self.agentStoryboard.instantiateViewControllerWithIdentifier("AgentProfile")
self.showViewController(otherVC as UIViewController, sender: otherVC)
let secondViewController = self.storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController
self.navigationController.pushViewController(secondViewController, animated: true)
How to i segue over to another UINavigationViewcController programmatically so there is a back button to go to the previous screen. I tried using this code, but it just models over.
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let resultViewController = storyBoard.instantiateViewControllerWithIdentifier("NavViewController") as FirstMemberViewController
self.presentViewController(resultViewController, animated:true, completion:nil)
Try this
// Your controllers
let navigationController = UINavigationController()
let viewController = UIViewController()
// The push
navigationController.pushViewController(viewController, animated: true)
I found the answer...
navigationController!.pushViewController(storyboard!.instantiateViewControllerWithIdentifier("Home") as! UIViewController, animated: true)