I have two table views (DayTVC & AddDayTVC). The title of the navigation item in the DayTVC represents the selected week. Is there a way to transfer the title of the navigation item (DayTVC) to a label on the AddDayTVC? I tried this
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "addDay" {
let destinationController = segue.destinationViewController as AddDayTableViewController
let sender = sender as DayTableViewController
destinationController.nameLabel.text = sender.navigationItem.title
}
}
But every time I trie to get to AddDayTVC I get the following error
Thread 1: EXC_Breakpoint (code=EXC_I386_BPT, subcode=0x0)"
for this line
let destinationController = segue.destinationViewController as AddDayTableViewController
Thanks in advance!
Since you're triggering the segue with a UIBarButtonItem, the sender will be that button and the cast:
let sender = sender as DayTableViewController
will fail and throw the indicated exception. Since this code is (probably) located in the DayTableViewController, why not just use self instead?
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 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)
}
I want to scan a QR code (doing this example: http://humberaquino.me/qrcode-scanning-in-swift/), however I have a problem with this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let barcodeViewController: BarcodeViewController = segue.destinationViewController as! BarcodeViewController
barcodeViewController.delegate = self
}
I got this:
When I change this to as!, I'm getting:
Thread 1: signal SIGABRT on this line.
If you have more than one segue on that view controller, it may be another one firing. checking segue.identifier is one way of making sure you're on the right one. If the behaviour is based on the class you can do this :
if let barcodeViewController = segue.destinationViewController as? BarcodeViewController
{
barcodeViewController.delegate = self
}
I have a navigation controller as the initial view. It goes to VC1 which has 3 buttons, and each button is tied to an action that sets a parameter in VC2 before invoking performSegueWithIdentifier("goNow", sender: nil). I have this in my VC1 too.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "goNow") {
if let sView: SViewController = segue.destinationViewController as? SViewController {
sView.action = self.action
}
}
}
When invoked, VC2 appears for a few seconds and it terminates with EXC_BAD_ACCESS.
I am not extremely familiar with Swift, but I know that there are some questions when attempting to compare strings. Instead of using:if (segue.identifier == "goNow")
~ edit ~
Setting the class in Interface Builder (storyboard) for the destination view controller.
Create a String Variable using the segue.identifier value and compare the two like this:
let segueID = String(segue.identifier)
let segueToOpen = "goNow"
let isEqual = (segueID == segueToOpen)
// Now your if statement
if isEqual {
// ...
}
Also, you might want to consider separating the logic in the next if statement to read something like:
let sView: SViewController = segue.destinationViewController
Here is an excerpt from RayWenderlick's site and using the as operator:
I have a tableview with buttons each containing a tag (according to indexPath.row), and when I press a particular button the details of the contents of that cell (which relates to a class called EventEntity) is meant to be passed through a 'prepareForSegue' method to another screen.
The value is assigned in the 'infoButtonDidPress' method as shown below:
func infoButtonDidPress(sender: UIButton){
eventPressed = eventEntities[sender.tag]
println (eventPressed.name) // prints the name, all good here.
}
The problem is that when I assign the contents of eventPressed to the destinationVC in 'prepareForSegue', they are nil. Code below:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "infoButtonSegue"){
var svc = segue.destinationViewController as! EventDetailsViewController;
println (eventPressed.name) // NOPE.
svc.name = eventPressed.name //also NOPE!
}
eventPressed is declared above viewDidLoad:
var eventPressed: EventEntity! = EventEntity()
The error I get when I try either of those lines with the 'NOPE' comment is 'Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Appname.EventEntity name]: unrecognized selector sent to instance 0x7fa280e16a50' error
Whats going on here?
Thanks in advance!
UPDATE
I have moved performWithSegue to the infoButtonDidPress method, but I am now unable to reference the destinationViewController.
My infoButtonDidPress now looks like this:
func infoButtonDidPress(sender: UIButton){
let eventPressed = eventEntities[sender.tag]
var destinationViewController: UIViewController = self.destinationViewController as EventDetailsViewController
// error: the current VC does not have a member named destinationViewController
self.performSegueWithIdentifier("infoButtonSegue", sender: self)
}
As you discovered, prepareForSegue is happening before infoButtonDidPress is called.
To fix this, instead of wiring the segue from the prototype cell in your tableView, wire it from the viewController icon at the top.
See this: How to wire segue from ViewController icon
Make sure to set the identifier to "infoButtonSegue". Then call the segue from infoButtonDidPress after you have set the value for eventPressed:
func infoButtonDidPress(sender: UIButton){
eventPressed = eventEntities[sender.tag]
self.performSegueWithIdentifier("infoButtonSegue", sender: self)
}
And then, in prepareForSegue pass the value to the destination view controller:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "infoButtonSegue") {
let dvc = segue.destinationViewController as! EventDetailsViewController
dvc.name = eventPressed.name
}
}