I currently have a button set to go to a TableViewController but decided I wanted to embed that TableViewController in a TabBarController. Well before I did this I had this bit of code in the previous ViewController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "showListSegue"){
let des = segue.destinationViewController as! TableViewController
des.jsonfile = self.jsonfile
}
}
Now when I try and click the button it give me this error.
Could not cast value of type 'UITabBarController' (0x111c818b0) to
'Forkit.TableViewController' (0x10d1b1490).
I tried the following code with no success as it gives me this error
Value of type "UITabBarController" has no member 'jsonfile'.
let des = segue.destinationViewController as! TableViewController
How can I get around this?
The segue showListSegue now has your TabBarController as it's destinationViewController. This is why it can not cast it to TableViewController, because it's not the one you're looking for. The TabBarController does contain a reference to the ViewController you want though. You likely have two options:
1: Use .viewControllers and find your view in there, like this:
let tabBarController = segue.destinationViewController as! UITabBarController
let des = tabBarController.viewControllers![0]
In which [0] selects which tab's ViewController you need.
2: Select the right tab and use .selectedViewController
let tabBarController = segue.destinationViewController as! UITabBarController
tabBarController.selectedIndex = 0 // choose which tab is selected
let des = tabBarController.selectedViewController!
Please be aware that you are working with optional values here, so either be absolutely sure you can safely unwrap, or build in checks (casting with as? and if let statements, etc.).
More information: UITabBarController Class Reference
Try This
#IBAction func about(sender: AnyObject) {
performSegueWithIdentifier("about", sender: sender)
}
Related
I am trying to pass data from a UIViewController to UITableViewController and I am getting the above SIGBRT Error Could not cast value of type 'UITableViewController' (0x113ccb7e0) to 'Racing_Weather.PredictorTableViewController' (0x1086645b0). . I have looked at the following solution. However, this did not seem to work. I have embedded a UINavigationController and the error appears in the following line let vc = predictorVC.topViewController as! PredictorTableViewController
Below is the full function for the segue.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "getPredictor" {
let predictorVC = segue.destination as! UINavigationController
let vc = predictorVC.topViewController as! PredictorTableViewController
vc.predictorTrack = TrackTextField.text!
vc.firstDriver = firstTextField.text!
vc.secondDriver = secondTextField.text!
vc.thirdDriver = thirdTextField.text!
}
You should check your storyboard to make sure that the top view controller in the navigation controller is actually a PredictorTableViewController. The error says that it's a UITableViewController. You might have to check the Identity Inspector in the top right hand corner of the storyboard editor to see if you have the class set correctly.
I'm trying to pass Realm data from Custom cell to Detail TableView Controller
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "viewTask" {
let nextViewController = segue.destinationViewController as! TaskViewTableViewController
let indexPath : NSIndexPath = self.tableView?.indexPathForSelectedRow as NSIndexPath!
let task = tasks![indexPath.row]
nextViewController.name = task.name
nextViewController.notes = task.notes
nextViewController.date = task.date
nextViewController.timeLength = task.timeLength
}
}
I'm getting error
Could not cast value of type 'Taskio.TaskListTableViewController'
(0x10001f028) to 'Taskio.TaskViewTableViewController' (0x10001f280).
Also tried
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "viewTask" {
let nav = segue.destinationViewController as! UINavigationController
let nextViewController = segue.destinationViewController as! TaskViewTableViewController
let indexPath : NSIndexPath = self.tableView?.indexPathForSelectedRow as NSIndexPath!
let task = tasks![indexPath.row]
nextViewController.name = task.name
nextViewController.notes = task.notes
nextViewController.date = task.date
nextViewController.timeLength = task.timeLength
}
}
and also
let nextViewController : TaskViewTableViewController = segue.destinationViewController as! TaskViewTableViewController
EDIT
Forgot to put class name into storyboard of tableViewController. It's working
For me the problem was i forgot to put class name in storyboard
It seems that your destinationViewController is not of the type that you are expecting. You will need to check the segue to make sure it's pointing to the correct controller. If it is, you'll need to revisit your controller class hierarchy.
Are TaskListTableViewController and TaskViewTableViewController part of the same class hierarchy? Per the Swift docs on typecasting, you can only downcast from TaskListTableViewController to TaskViewTableViewController if your List view is a subclass of your Task view. It is not enough that both are simply subclasses of UITableViewController.
In other words, if your class hierarchy looks like this, you will not be able to downcast from the List view to the Task view:
----> TaskListTableViewController
/
UITableViewController
\
----> TaskViewTableViewController
But if your hierarchy looks like this, you will be able to downcast from one to the other:
UITableViewController -> TaskListTableViewController -> TaskViewTableViewController
Regarding your second attempt at casting to UINavigationController, the navigation controller is not related to UITableViewController at all, so it cannot be type casted to that class either.
You can check out the inheritance hierarchy for UINavigationController and UITableViewController. One needs to be a subclass of the other for any type casting to work. You'll see that is not the case.
If I understand from the error message, you are attempting to cast a TaskListTableViewController to TaskViewTableViewController.
The destination is a TaskListTableViewController so you have to treat it like one.
let nextViewController = segue.destinationViewController as! TaskListTableViewController
I have a login screen that takes credentials, and based on outcome of verification, user is redirected to another view controller or not. The login view controller is controlled by NavigationController and once the login is successful, user is redirected to a Home view controller controlled by UITabBarController.
When I trigger the segue, it says the following error:
Could not cast value of type 'UITabBarController' (0x10d414030) to
'Mawq.HomeViewController' (0x10a7ed220).
Here is the code for the segue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "showHomeFromLoginSegue") {
/*Provide ServiceToken a value from API*/
// pass data to next view
let destinationVC = segue.destinationViewController as! HomeViewController
destinationVC.userObject = self.userObject;
}
}
Any idea how to overcome this issue?
Since your segue is connected to a UITabBarController, you need to cast it to UITabBarController and get the ViewController object using the viewControllers property of the tab bar controller.
let tabCtrl = segue.destinationViewController as! UITabBarController
let destinationVC = tabCtrl.viewControllers![0] as! HomeViewController // Assuming home view controller is in the first tab, else update the array index
destinationVC.userObject = self.userObject;
For Swift 4:
let tabCtrl: UITabBarController = segue.destination as! UITabBarController
let destinationVC = tabCtrl.viewControllers![0] as! HomeViewController
destinationVC.userObject = userObject[String!] // In case you are using an array or something else in the object
I am very new to the swift language and am trying to make an app that would do some basic calculations. The problem I am running into is that I want to use the values from an array that is declared in one viewcontroller in another viewcontroller to do calculations.
I declare the array in the first viewcontroller like this:
var array2 = [Double]()
And then I have no idea how to access this in the second view controller. I have tried looking at previous questions as well as online tutorials and have had no success.
Any help is greatly appreciated. Thank you in advance.
in VC2 create global var array2 = [Double]()
add following override func to body of VC1
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let DVC = segue.destinationViewController as! ViewController2 //replace ViewController2 with the name of your 2nd VC
DVC.array2 = array2
}
Overall, what you are doing is telling VC1 to copy VC1's array2 to VC2's array2, before the segue happens.
As your app becomes more complex, if your VC1 has more than 1 segue...meaning can go to multiple different VC's...you'll need to change your prepareForSegue so that it takes into account for this.
One way to do this is to change it to
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SegueIdentifier you give to that particular segue in identityInspector" {
let DVC = segue.destinationViewController as! ViewController2 //replace ViewController2 with the name of your 2nd VC
DVC.array2 = array2
}
}
Background: I want to display a modal segue from a UITableViewController(A) to a UITableViewController(B), but I want to show a NavigationBar to "Cancel" and "Save".
What I've done:
In storyboard:
I ctrl drag the cell from A to B, and set segue identifer "selectItem"
I choose B and select "Editor - Embed in - Navigation Controller"
In A's ViewController:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifer == "selectItem" {
if let indexPath = self.tableView.indexPathForSelectedRow() {
let destinationViewController = segue.destinationViewController as B
// Pass value from A to B
}
}
}
Error:The app crashed at let destinationViewController = segue.destinationViewController as B with the error swift_dynamicCastClassUnconditional. If I didn't embed a navigation controller to B, the program would not crash. But I really need a navigation bar.
Is there any solution or other way to achieve this? Thank you!
PS: I tried drag a NavigationBar from object library in storyboard, but it's miss a part of background to cover statusbar...
Create both of the UITableViewController in your storyboard.
Select your Second UITableViewController (the one you want to present modally), and embed it in an UINavigationController.
Add the "Cancel" and "Save" UIBarButtonItem into UINavitionItem of the Second UITableViewController.
Select the UITablViewCell of your First UITableViewController
Control+Drag into your UINavigationController.
Select "Present Modally" under the "Selecteion Segue" option from the dropdown list.
To pass data in your First UITableViewController override the method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "identifier" {
let destination = segue.destinationViewController as UINavigationController
let bViewController = destination.topViewController as BViewController
// pass data
}
}
Here are the screenshots:
This should do the job, Cheers!
I solved it!
I added a BreakPoint at the line let dest = segue.destinationViewController as B, and I found that segue.destinationViewController is NavigationController type. So I fixed it by replacing this line to:
let dest = segue.destinationViewController as UINavigationController
let bVC = dest.topViewController as B
and do some passing value stuff.
Hope this will help other people facing this problem.
I use
if let b = segue.destinationViewController.childViewControllers.first as? B {
//do something with b
}
for this scenario. It is really just a syntax difference though.