I currently have a storyboard that has a tableview with my data, and I believe I correctly pass that data using the didSelectRowAtIndexPath and the prepareForSegue functions.My problem is that when I select a certain cell my cast becomes incorrect because I have a tab bar controller holding my views to be displayed with this segued information.I want my cast to be:
let destination = segue.destinationViewController as! DownloadViewController
But I am getting an error because the segue is going to the tab bar controller first. This error makes perfect sense to me but I am unsure how to get around it without getting rid of the tab bar controller completely. Here is a picture of my story board to help show the overall flow.
http://imgur.com/7gFKKIZ
Any help is appreciated.
The UITabBarController has an array that contains its connnected viewController, to access e.g. the first one try
let destination = (segue.destinationViewController as! UITabBarController).viewControllers?.first as! DownloadViewController
Instead of using segue, you can use a modal presentation of your desired first tab for display if it works for you.
let displayFirstVC = storyboard.instantiateViewControllerWithIdentifier("newVC") as! UIViewController
self.presentViewController(displayFirstVC , animated: true, completion: nil)
When you instantiateViewControllerWithIdentifier, you have to create a storyboard name for your FirstViewController with name newVC.
You would also need to replace UIViewController with the name you gave your view controller.
More details here.
Instantiate and Present a viewController in Swift
Related
I have a viewController related to a Tab Bar Controller: the first one.
Clicking on a cell of its tableview, I'll show programmatically another viewController that's not linked to the first viewController with no segue (because of right reasons).
Now, my goal is to present/instantiate the second viewController related to the tab bar mentioned at the beginning of this question.
If I'll use this:
let vc=storyboard?.instantiateViewController(withIdentifier: "offerteView") as! SecondViewController
It'll be presented the mentioned viewController without the tab bar of course.
How can I solve it?
Embed the first view controller in a navigation controller and use its pushViewController function to show the second view controller.
let vc = storyboard?.instantiateViewController(withIdentifier: "offerteView") as! SecondViewController
navigationController?.pushViewController(vc, animated: true)
when using tab bars the view controllers are called on the basis of their Index and because of this the tab bars are still maintained and this can be done like this.
self.tabBarController!.selectedViewController! = self.tabBarController!.viewControllers[3]
where [3] is the index position of the View Controller.
or
self.tabBarController.selectedIndex = 1;
//Hope it was helpful. Happy Coding.
I'm trying to send some values from one viewcontroller to another. (all embedded in NavigationController). I could make segue with normals viewcontrollers so in general I understand a segue idea. I've to do that in two different ways and got two different problems.
First way, segue does right but "two times". I mean after segue (which I want) there is another segue to same controller but without navigation controller and without data I would send. The "back" button on last viewcontroller is returning to AlmostViewController.
Here's code:
Second way, Nothing happened,
ErorCould not cast value of type 'RevisionApp.AlmostViewController'
(0x1055d58c0) to 'UINavigationController' (0x107669f18).
Here's code:
For the first Problem, When using embedded in navigation controller you have don't have to create action function when the button is tapped. Navigation controller does it for you. So things you need to do :
Disconnect the function btnTapped from the button using storyBoard.
Delete or comment the function btnTapped(You don't need it).
Problem is line number 18. You are trying to cast AlmostViewController to a UINavigationController. Directly access like this,
let detailController = segue.destination as! AlmostViewController
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("ViewController2") as NextViewController
self.presentViewController(nextViewController, animated:true, completion:nil)
I searched for similar problems, but none solved my problem. I need to call a new view controller , but when I do it a black screen appears , as I do to associate with the main storyboard screen?
Here is my suggestion:
let vc = storyboard!.instantiateViewControllerWithIdentifier("viewIdentifier") as! viewNeedToCall
You can init and use vc with navigation.
A black screen appears when the simulator can't figure what to present. It seems lost in the sense which controller it has to present.
If it is the first screen then make sure that you have set the initial view controller in Main.storyboard. If not, then you have to call(instantiate) that view controller using the instantiateViewControllerWithIdentifier property of a storyboard.
For e.g.If you want to present a ViewController named as YourViewController then
Make an object of YourViewController, say yourVCObject.
let yourVCObject = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewController") as? YourViewController
Present your desired ViewController with -
self.presentViewController(yourVCObj!, animated: true, completion: nil)
Here connect your class YourViewController in the Identity Inspector in the "Class" and type "YourViewController" in the Storyboard ID and check the "Use Storyboard ID"
Looks like you forgot to connect your VCs to a NAVIGATION CONTROLLER.
Without Navigation controller you cannot move to another VC.
I have two VCs: VC1 and VC2.
In VC1, I have a finish button which I programmatically made and a result array I want to pass to VC2.
I know how to make Segue in Storyboard, but I cannot do that at this moment since the finish button is programmatically made.
If I want to pass result array using segue, is there a way to make the segue programmatically? If this is not possible, should I just present VC2 using presentViewController and set a delegate to pass the result array?
You can do it like proposed in this answer:
InstantiateViewControllerWithIdentifier.
Furthermore I am providing you the code from the linked answer rewritten in Swift because the answer in the link was originally written in Objective-C.
let vc = UIStoryboard(name:"Main", bundle:nil).instantiateViewController(withIdentifier: "identifier") as! SecondViewController
vc.resultsArray = self.resultsArray
EDIT:
Since this answer draws some attention I thought I provide you with another more failsafe way. In the above answer the application will crash if the ViewController with "identifier" is not of type SecondViewController. In Swift you can prevent this crash by using optional binding:
guard let vc = UIStoryboard(name:"Main", bundle:nil).instantiateViewControllerWithIdentifier("identifier") as? SecondViewController else {
print("Could not instantiate view controller with identifier of type SecondViewController")
return
}
vc.resultsArray = self.resultsArray
self.navigationController?.pushViewController(vc, animated:true)
This way the ViewController is pushed if it is of type SecondViewController. If can not be casted to SecondViewController a message is printed and the application remains on the current ViewController.
You can still create the segue in Interface Builder by dragging from VC1 to VC2 - just drag from/to the little yellow circle at the top of the VC. Give this segue a unique name in IB, and in your finish function you can call performSegueWithIdentifier:, pass in the name of your segue, and that's it. In the prepareForSegue method you can find out which segue is being performed by accessing segue.identifier, and if it's the segue in question you can get a pointer to segue.destinationViewController and pass your data on that way.
I want to switch between different view controllers, here is my codes,
let sb = UIStoryboard(name:"Main", bundle: nil)
let vc = sb.instantiateViewControllerWithIdentifier("tabBarController") as ViewController
self.presentViewController(vc, animated: true, completion: nil)
'tabBarController' is the storyboad ID I had wrote in the identifier inspector.but I got some error at this line.
let vc = sb.instantiateViewControllerWithIdentifier("tabBarController") as ViewController
and here is the screenshot,
What's the problem?
And I have another question, here is the screenshot after the sb was initialized, the storyboardFileName is "Main.storyboardc", shouldn't it be "Main.storyboard"?
Thanks very much!!!!
The error is saying that the view controller returned by instantiateViewControllerWithIdentifier cannot be cast to a ViewController.
This is probably because you did not set the Custom Class property of your view controller in the storyboard to ViewController.
Go to your storyboard, select your view controller, then open the Identity inspector and look for the Custom Class property. Set it to ViewController and tab out of the field to make sure it takes. Then run again.