Push another Viewcontroller from action button in xib file - ios

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.

Related

How can i pop back from storyboard of framework?

let storyboardBundle = Bundle(identifier: "SignUPFramework")
let vc = UIStoryboard.init(name: "SignIn", bundle: storyboardBundle).instantiateViewController(withIdentifier: "SignInViewcontroller") as! SignInViewcontroller
navigationController?.pushViewController(vc, animated: true)
I have navigated to storyboard of framework as above.
You own the navigationController. So you can use either popViewController(animated:) (if you are sure that there is only one view controller you wish to pop), or popToViewController(_:animated:), or popToRootViewController(animated:) (if you wish to return to the root).
It does not matter that the storyboard is in a framework. You still own the view hierarchy, the navigation stack and the view controller instance you get from the below line of code
let vc = UIStoryboard.init(name: "SignIn", bundle: storyboardBundle).instantiateViewController(withIdentifier: "SignInViewcontroller") as! SignInViewcontroller
So you can do whatever you want with it in terms of navigation (push it and pop it or present it and dismiss it).
You just need to identify at what point you want to trigger any of these actions.
I think you are using xib so it will not return action first you should do protocol for callback to view controller then you can use popViewController(animated:).
protocol CallBackDelegate: AnyObject {
func back()
}
//Delegate
weak var delegate:CallBackDelegate?
#IBAction func buttonAction(_ sender: Any) {
delegate?.back()
}
Now you can use protocol in view controller
class ViewController: UIViewController, CallBackDelegate {
func back() {
navigationController?.popViewController(animated: true)
}
}
Note :- Confirm delegate variable in cellForRowAtIndexPath i.e.
cell.delegate = self
I have solved it by
let bundle = Bundle(for: SignInViewcontroller.self)
let vc = UIStoryboard.init(name: "SignIn", bundle: bundle).instantiateViewController(withIdentifier: "SignInViewcontroller") as! SignInViewcontroller
in above snippet instead of passing bundle id i have passed viewcontroller itself.

How to push a new view controller from a view

I created a view in .xib. On it, I placed a button on which I want to open another ViewController. I assigned a storyboardID to this ViewController. But I can't push the new controller, how can this problem be solved?
My code:
class MyView: UIView {
...
#IBAction func buttonPressed(_ sender: Any) {
let storyboard = UIStoryboard.init(name: "ViewController", bundle: Bundle.init())
let vc = storyboard.instantiateViewController(withIdentifier: "VC") as! ViewController
let navigationController = UINavigationController.init()
navigationController.pushViewController(vc, animated: true)
}
...
}
class ViewController: UIViewController {
...
}
Xcode gives this error:
'Could not find a storyboard named' ViewController'
but I checked there are no errors. I reloaded Xcode - no result.
Seems you have more than one issue.
You are trying to push a UIViewController into a non presented UINavigationController
You are creating an instance from a UIStoryboard with wrong identifier
First you need to choose the correct UIStoryboard which I am assuming it's main, then you have to present the UINavigationController from the holder UIViewController or trying to push from that UIViewController if it's has a UINavigationController,
Part 1: Fixing the instances,
let storyboard = UIStoryboard.init(name: "main", bundle: Bundle())
let vc = storyboard.instantiateViewController(withIdentifier: "VC") as! ViewController
let navigationController = UINavigationController(rootViewController: vc)
Now you have a navigationController that holds a your VC
Part 2: You want to present this navigation from your holding VC you can either add a listener to the UIButton from that VC and present/push from there
so lets wrap this up create a function in your VC that holds the UIView
#objc func pushToMyVc() {
let storyboard = UIStoryboard.init(name: "main", bundle: Bundle())
let vc = storyboard.instantiateViewController(withIdentifier: "VC") as! ViewController
let navigationController = UINavigationController(rootViewController: vc)
}
And in your UIView add this variable var selector: (() -> Void)?
Now in #IBAction func buttonPressed call this function selector?()
Now all we need is to pass what function I want to use when this button gets clicked in our case the function pushToMyVC that we put in our main UIViewController so in our didLoad or wherever you're calling this custom view
set the selector like this
myView.selector = pushtoMyVC
Side Note: you can't present/push UIViewController from non
UIViewController classes
Try changing how you fetch the storyboard from
let storyboard = UIStoryboard.init(name: "ViewController", bundle: Bundle.init())
to
let storyboard = UIStoryboard(name: "ViewController", bundle: nil)
note that the storyboard ID needs to be exactly ViewController.
If this still shows the same error, I'd say you have an issue with the storyboard target membership, so check that in the file inspector on the right side of the Xcode editor.
You should check your Storyboard file name again, because when you want to initiate a UIViewController from a Storyboard file, the name parameter in UIStoryboard initiation has to be exactly the same as the Storyboard file name.
#IBAction func buttonPressed(_ sender: Any) {
// Let's say that you have a Storyboard file named ViewController.storyboard and a UIViewController class named ViewController.swift
let destinationVC = UIStoryboard(name: "ViewController", bundle: nil).instantiateViewController(withIdentifier: "VC") as! ViewController
self.navigationController?.pushViewController(destinationVC, animated: true)
}
Hope this helps your issue
you should take a delegate back to viewController that contains current view, and call navigationController.push from there

Swift tried to present modally an active controller [Current view controller] even though the presented controller is another one

I have read some answers like dismissing the current ViewController but my situation is different because I am presenting another ViewController.
This code presents the view controller with its navigation controller although I cannot access it's properties:
#IBAction func didTouchAddFriend(_ sender: UIButton) {
DispatchQueue.main.async {
let storyBoard = UIStoryboard(name: "CustomContact", bundle: nil)
let customContactVC = storyBoard.instantiateViewController(withIdentifier: "CustomContact")
}
}
While this one doesn't work
#IBAction func didTouchAddFriend(_ sender: UIButton) {
DispatchQueue.main.async {
let navigation = UIStoryboard.init(name: "CustomContact", bundle: nil).instantiateInitialViewController() as! UINavigationController
let pickerUserVC = navigation.viewControllers.first as! CustomContactsViewController
self.present(pickerUserVC, animated: true, completion: nil)
}
}
I have another story board named CustomContact.storyboard which containts a CustomContactsViewController
When I click the didTouchAddFriend, it just shows me this error:
'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <Main.MainViewController: 0x7ff29f06ac00>.'
I cannot understand the error cos when I printed the value of pickerUserVC, it show the right view controller:
<Main.CustomContactsViewController: 0x7fd1b7922400>
MainViewController is the current view controller implementing the didTouchAddFriend function
You ought to present the navigation controller (which hosts the CustomContactsViewController as it's root view controller).
Moreover, you can skip the Dispatch call, since we are in an #IBAction which already runs in the main thread:
#IBAction func didTouchAddFriend(_ sender: UIButton) {
let navigation = UIStoryboard.init(name: "CustomContact", bundle: nil).instantiateInitialViewController() as! UINavigationController
let pickerUserVC = navigation.viewControllers.first as! CustomContactsViewController
self.present(navigation, animated: true, completion: nil)
}

How to instantiate a navigation controller from another view controller?

My goal is whenever i click a button on a first view controller, then it will navigate to another controller which is a navigation controller.
firstViewController and secondViewController has no connection or anything.
Picture
I used this code
#IBAction func buttonTapped(sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("secondViewCtrl") as! SecondViewController
self.presentViewController(vc, animated: true, completion: nil)
}
The reason why i instatiate so that I could pass data like
vc.name = "Myname"
The problem with this code is that it doesn't present navigation bar and as well as the tab bar. What should I do to show both?
Updated question
#IBAction func buttonTapped(sender: UIButton) {
guard let tabBarController = tabBarController else { return }
tabBarController.selectedIndex = 1
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("trackYourGenie") as! TrackYourGenieViewController
let navController = tabBarController.viewControllers![1]
let secondViewController = navController.topViewController
vc.name = "Myname"
}
You are instantiating the view controller hence you wouldn't get the navigation bar. To get the navigation bar please instantiate navigation controller and since the second view is only child you would get the second view by default.
#IBAction func buttonTapped(sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("Navigation Controller Id") as! UINavigationController
self.presentViewController(vc, animated: true, completion: nil)
}
The above code should give you the navigation bar.
A safe approach:
guard let tabBarController = tabBarController else { return }
tabBarController.selectedIndex = 1
If you need to access to your tabBarController to pass datas you can do simply:
let navController = tabBarController.viewControllers[1]! as! UINavigationController
let secondViewController = navController.topViewController
Your method could be:
#IBAction func buttonTapped(sender: UIButton) {
guard let tabBarController = tabBarController else { return }
let navController = tabBarController.viewControllers[1]! as! UINavigationController
let secondViewController = navController.topViewController as! SecondViewController
secondViewController.name = "my name"
tabBarController.selectedIndex = 1
}
In your case, the following code should be sufficient :
self.tabBarController.selectedIndex = 1
As UITabBarController is your rootViewController, you can access it with self.tabBarController. You don't have to instantiate UINavigationController as it is in the storyboard.
I can see from your StoryBoard that you have a TabBarController. If your configuration is that and FirstViewController is on first tab and SecondViewController on second tab, you can just change TabBarController selectedIndex property:
#IBAction func buttonTapped(sender: UIButton) {
tabBarController?.selectedIndex = 1
}
If you want to pass data to SecondViewController you can try one of these solutions:
let controller = tabBarController.viewControllers[1] as SecondViewController!
controller.data = "some data"
This soultion could not work since SecondViewController is not ready yet.
Create a singleton class where to save data, then retrieve data in SecondViewController viewDidLoad method
Save data in UserDefaults, then retrieve data in SecondViewController viewDidLoad method (bad solution if information doesn't have to be persistent)
Extend UITabBarController and use it, create a custom var in tabBarController, put data in that variable and then retrieve data in SecondViewController viewDidLoad method
Then clear data if needed.
Navigation will not work from firstViewController as to navigate something we need UINavigationController.
Try Like This

Swift Xcode Button not showing next view

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.

Resources