I'm trying to code a button that simply switches to the next view. So I embedded the first ViewController into a navigation controller then I dragged in another view controller, created a new class name ViewController2 and associated that class with the second ViewController and came the second view controller a storyboard id:"view2". Then in the Button's function I added this code:
#IBAction func newGamePressed(sender: AnyObject) {
let view2 = self.storyboard?.instantiateViewControllerWithIdentifier("view2") as
ViewController2
self.navigationController?.pushViewController(view2, animated: true)
}
However when i click on the button, literally nothing happens!!! what am i doing wrong???
#IBAction func newGamePressed(sender: AnyObject) {
let VC1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("view2")
let navController = UINavigationController(rootViewController: VC1)
self.presentViewController(navController, animated:true, completion: nil)
}
Just try with this code.
Related
How can I show() or persent() VC on button touch? What code should I write?
First, using Storyboards
If you are working with storyboard. You should connect your button view storyboard.
#IBAction fileprivate func handlePresentingView(_ sender: UIButton) {
let vc = SecondVC()
present(vc, animated: true, completion: nil)
}
Second, programmatically
1: If you are working programmatically
in viewDidLoad add the following line.
mybutton.addTarget(self, action: #selector(handlePresentingVC(_:)), for: .touchUpInside)
2: Your action method
#objc func handlePresentingVC(_ sender: UIButton) {
let vc = SecondVC()
present(vc, animated: true, completion: nil)
}
In my example, I'm assuming that you don't have a storyboard file for
your SecondVC view controller.
If SecondVC is connected to a storyboard view controller, you will
need to change the instantiation of your secondVC object inside of
your button's action method.
1: Select your SecondVC's view controller in your storyboard.
2: Add a Storyboard ID to it.
3: Change your button's action method to the following.
#objc func handlePresentingVC(_ sender: UIButton) {
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let secondVc = storyboard.instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
present(secondVc, animated: true, completion: nil)
}
In Swift 5 and iOS 13
The default modal presentation style is a card. This shows the previous view controller at the top and allows the user to swipe away the presented view controller.
To retain the old style you need to modify the view controller inside of your button's action method like this:
secondVc.modalPresentationStyle = .fullScreen
This is the same for both programmatically created and storyboard created controllers.
I have a few view controllers with navigation bar and tab bar. Then I have an initial view controller with no navigation bar and tab bar. I want to go back to the initial view controller with no other view controllers in stack. Here's what I do:
// Head back to Initial View Controller.
let initialViewController = self.storyboard!.instantiateViewController(withIdentifier: "Initial")
UIApplication.shared.keyWindow?.rootViewController = initialViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = initialViewController
This works perfectly. But then it doesn't move to another view controller from the initial view controller again. For example:
#IBAction func loginButton(_ sender: Any) {
print("Login Button Tapped.")
let storyboard = UIStoryboard(name: "SignInViewController", bundle: nil)
let signInViewController = storyboard.instantiateViewController(withIdentifier: "SignInViewController") as! SignInViewController
self.navigationController?.show(signInViewController, sender: nil)
}
Here, the print statement is run, but self.navigationController.show won't. How do all this work? And what's the right approach to accomplish this?
EDIT:
To avoid any confusion, here's my storyboard. The left most viewcontroller (pink screen) is the initial view controller I want to go back to. The right most on the same level is the view where I want to go back from.
It doesn't move to another view controller, because you are setting a simple view controller in your rootViewController.
What you need is:
let initialViewController = self.storyboard!.instantiateViewController(withIdentifier: "Initial")
let navController = UINavigationController.init(rootViewController: initialViewController)
UIApplication.shared.keyWindow?.rootViewController?.present(navController, animated: true, completion: nil)
This will create a navigationviewcontroller, so when on "Initial" you should be able to perform push, present actions of another view controllers.
From your initial view controller, you need to instantiate your navigation stack and present it modally. Then, when you want to get back to your pre-navigation initial VC, just call dismiss(animated:,completion:), which will dismiss your entire navigation stack and return you to the initial view controller.
self.navigationController.popToRootViewController(animated:) is what you're looking for.
https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621855-poptorootviewcontroller
EDIT
Try dismissing the navigationController after calling popToRoot.
self.navigationController.dismiss(animated: true, completion: nil)
EDIT
Try the following:
#IBAction func loginButton(_ sender: Any) {
print("Login Button Tapped.")
let storyboard = UIStoryboard(name: "SignInViewController", bundle: nil)
let signInViewController = storyboard.instantiateViewController(withIdentifier: "SignInViewController") as! SignInViewController
present(signInViewController, animated: true, completion: nil)
//self.navigationController?.show(signInViewController, sender: nil)
}
Then to dismiss the signInViewController call self?.navigationController.dismiss(animated:true, completion:nil) from inside the signInViewController.
I've got a button on storyboard Alpha that leads to storyboard Beta using the following code:
#IBAction func showBeta(_ sender: Any) {
let storyboard = UIStoryboard(name: "Beta", bundle: nil)
let bvc = storyboard.instantiateViewController(withIdentifier: "BetaViewController") as! BetaViewController
self.present(bvc, animated: true, completion: nil)
}
This works without any problems.
However, I ran into the issue of not having a back button in Beta because self.present makes the new view appear modally.
I then read this post where the poster had the same problem as me. The answer suggested this code:
self.navigationController?.pushViewController(viewController: UIViewController, animated: Bool)
So I changed my code to:
#IBAction func showBeta(_ sender: Any) {
let storyboard = UIStoryboard(name: "Beta", bundle: nil)
let bvc = storyboard.instantiateViewController(withIdentifier: "BetaViewController") as! BetaViewController
self.navigationController?.pushViewController(bvc, animated: true)
}
However, now nothing happens at all when clicking the button. No errors, nothing. What's going on here?
It seems your AlphaViewController isn't embedded in a UINavigationController.
Try this piece of code:
#IBAction func showBeta(_ sender: Any) {
let storyboard = UIStoryboard(name: "Beta", bundle: nil)
let bvc = storyboard.instantiateViewController(withIdentifier: "BetaViewController") as! BetaViewController
show(bvc, sender: self)
}
This will cause your BetaViewController appear modally if your AlphaViewController isn't embedded in navigation controller and you won't get the back button. But if your AlphaViewController is embedded in navigation controller then your BetaViewController will be shown as left-to-right transition and you will get your desired back button.
To add navigation controller:
If you added your AlphaViewController from interface builder, follow this to embed it in a navigation controller: SelectAlphaViewController -> Editor -> Embed In -> Navigation Controller
Or, if you added your controller programmatically, you can check this answer.
I have a view controller as my initial view controller.
there's a button in it(GO button) which when the user taps, it should go to another view controller(let's call it Destination view controller with label 'This is where i wanna go'). Meanwhile i want to pass it through a Tabbar controller. The reason is i want to have tabbar in my navigation stack and when users presses back on Destination view controller, it must go to tabbar controller. Picture shows what i want. what can I do to skip tabbar while having it in navigation stack?
You can do that easily inside the IBAction of GO button:
#IBAction func goTapped(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc1 = storyboard.instantiateViewController(withIdentifier: "myTabBarViewController")
let vc2 = storyboard.instantiateViewController(withIdentifier: "myGoalViewController")
let controllers = [vc1, vc2]
self.navigationController!.setViewControllers(self.navigationController!.viewControllers + controllers, animated: true)
}
Good luck!
Going to DestinationViewController could be manually:
if let destinationViewController = self.storyboard?.instantiateViewController(withIdentifier: "Storyboard ID of DestinationViewController") {
self.navigationController?.pushViewController(destinationViewController, animated: true)
}
(Alternatively, you could make a segue from FirstViewController to the DestinationViewController directly in Storyboard)
And in your DestinationViewController, insert the TabbarController to the Navigation sequence manually after view did appear, then you are able to go back to the TabbarController:
class DestinationViewController: UIViewController {
//......
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if self.isBeingPresented || self.isMovingToParentViewController {
var viewControllers = self.navigationController?.viewControllers
if let index = viewControllers?.endIndex.advanced(by: -1),
let tabBarController = self.storyboard?.instantiateViewController(withIdentifier: "Storyboard ID of TabBarController") {
viewControllers?.insert(tabBarController, at: index)
self.navigationController?.viewControllers = viewControllers!
}
}
}
//......
}
I have a viewcontroller that presents from a .xib.
Inside the .xib there is a button; I want the button to pushviewcontroller to an other viewcontroller (ViewControllerPeopleNew).
I use an action button:
#IBAction func _hitPeople(sender: AnyObject) {
let mapViewControllerObejct = self.storyboard?.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
But got an error:
Signal SIGABRT
unrecognized selector sent to instance
I already checked all about name identifier viewcontroller and all is right.
From view controller present with XIB you can not get storyboad use below code
#IBAction func _hitPeople(sender: AnyObject) {
let storyboard = UIStoryboard(name: "storyboadname", bundle: nil)
let mapViewControllerObejct = storyboard.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
Always remember that you can only use self.storyBoard to instantiate a view controller when both the view controllers (To and From view controllers) belong to the same storyboard. If not then you need to first get a reference to the storyboard your To view controller belongs to. So you need to do this:
#IBAction func _hitPeople(sender: AnyObject) {
let stotyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let mapViewControllerObejct = storyboard?.instantiateViewControllerWithIdentifier("peoplenew") as? ViewControllerPeopleNew
self.navigationController?.pushViewController(mapViewControllerObejct!, animated: false)
}
PS: Just be sure that your From view controller is in the navigation stack i.e. self.navigationController is not nil.