Thread 1: Signal SIGABRT with segue in swift - swift

I have several tableview. I am trying to make a simple application and after adding more view when I get the third tableView this error "Thread 1 Signal SIGABRT" and the app wont open in iOS Simulator. The error points to this line of code:
let VC :DetailCityTableViewController = segue.destinationViewController as! DetailCityTableViewController
and display error :
Could not cast value of type 'UITableViewController' (0x102af47f8) to 'balen.DetailCityTableViewController' (0x1013d7560).
(lldb)
Full Code :
tableview2 pass to tableView3
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let path : NSIndexPath = self.tableView.indexPathForSelectedRow!
if segue.identifier == "DetailCitySegue" {
let VC :DetailCityTableViewController = segue.destinationViewController as! DetailCityTableViewController
VC.urlDetailCity = urlDetail!// pass url city
VC.cityIdSelectet = cityId[path.row] //pas CountryID selected
print(cityId[path.row])
}
}
I am , I think the problem is segue .What do you think?

No, the problem is '
Could not cast value of type 'UITableViewController' (0x102af47f8) to
'balen.DetailCityTableViewController''
You didn't change the class type of the view controller to DetailCityTableViewController in interface builder or the segue has a different destination than you think.

Related

Variable shared between view controllers of storyboard?

My app is split into 2 storyboards: a character selection one and a main application one. When the user selects a character the app segues's to the main application, and all the views of that storyboard should now relate to the character the user selected.
I'm trying to find out the best way to share a String that will have the selected character's information between all the main application storyboard's views. Right now I'm using UserDefaults to just set a global variable:
func loadMainApp(sender: UITapGestureRecognizer) {
let currentCharcter = allCharacters[(sender.view?.tag)!]
let defaults: UserDefaults = UserDefaults.standard
defaults.setValue(currentCharacter, forKey: "CurrentCharacter")
performSegue(withIdentifier: "MainAppSegue", sender: self)
}
From there all the view controllers in the Main App storyboard can fetch the string from UserDefaults.
Is this the best way of doing such a thing or is there a better way?
The better way is to pass the character to the viewController you are segueing to, and the easiest way to do that is with prepare(for segue. If you change your performSegue call to pass the sender on by saying performSegue(withIdentifier: "MainAppSegue", sender: sender) you will be able to access that in prepare(for like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//Safely check to make sure this is the correct segue by unwrapping the sender and checking the segue identifier
if let tapGesture = sender as? UITapGestureRecognizer, let tapGestureView = sender.view, let mainViewController = segue.destination as? MainViewController, segue.identifier == "MainAppSegue" {
//Get a reference to the character that was selected
let currentCharacter = allCharacters[tapGestureView.tag]
//Pass the character to the new viewController
mainViewController.character = currentCharacter
}
}
I made a couple assumptions about the name of the viewController you are performing the segue to, and assumed it has a variable called character where you can send your character. Your new viewController now has a reference to the character.
If I understand you well. Personally I am using Singeltons for achieving Global variable between Views rather than UserDefaults
class SomeClass{
static let sharedInstance = SomeClass()
var someString = "This String is same from any class"
}
Usage inside of some function :
SomeClass.sharedInstance.someString = "Changing Global String"

Is it possible to have 2 times prepare for segue for 2 different view controllers?

I am swift beginner and I am struggling with my first application. Sorry if my question is too basic, but I get an error message in my code here:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
let secVC: NavigationViewController = segue.destinationViewController as! NavigationViewController // here is the error
secVC.receiveImeNaSladkarnica = Label1.text!
secVC.KordaA = Shirina.text!
secVC.KordaB = Duljina.text!
secVC.PodImeNaObekt = Label2.text!
I have created 2 different buttons: Navi Me and More Info buttons.
The first one (Navi Me) is connected with another view controller which is called NavigationViewContorller, there I send all of the data I need by using prepare for segue. Everything was working perfect, but now I have created another button which is called (MoreInfo).It is connected with 3rd viewcontroller called MoreInfoViewController. I think I have connected everything fine, but still when I click on the MoreInfo button the app stops working and I get the following error: Thread 1: signal SIGBART in the marked line. I cannot understand why is it breaking when this segue is for another view controller, nt for the MoreInfoViewController. Would you please advice me what to do or provide me with an example how to fix it
I have tried that:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
switch segue.identifier {
//error here-> case "VC1" :
let secVC: NavigationViewController = segue.destinationViewController as! NavigationViewController
secVC.receiveImeNaSladkarnica = Label1.text!
secVC.KordaA = Shirina.text!
secVC.KordaB = Duljina.text!
secVC.PodImeNaObekt = Label2.text!
//error here -> case "VC2" :
let secVC2: MoreInfoViewController = segue.destinationViewController as! MoreInfoViewController
secVC2.receiveImeNaSladkarnica = Label1.text!
secVC2.KordaA = Shirina.text!
secVC2.KordaB = Duljina.text!
secVC2.PodImeNaObekt = Label2.text!
default:
break
It still doesn't work
Each segue is supposed to have an unique string identifier.
For multiple view controllers use a switch statement
switch segue.identifier {
case "vc1" :
// prepare to go to vc1
case "vc2" :
// prepare to go to vc2
default : break
}
Once again my yesterday comment:
Since you are a beginner in Swift please learn first to consider the naming convention that variable names start with a lowercase letter.

Passing Core Data objects from UITableViewCell to another View Controller

Currently I have the application loading up the data in a tableview presented to the user that I want them to select the object they wish to view further details about. From their I want to be able to read out the data in the object to the user in various forms either labels or a tableview dependent on the data.
I have been reading around and trying to understand this stuff but it is all still new to me! I had another guy on here help me out with saving the data and passing the data around to store but reading it out is a seemingly different thing. Any examples in swift language would lead me down the right path I know that I need to use the didselectrow method and call a segue and also that I need a prepare for segue but I am not quite sure how it should look.
I have read multiple posts and some do actually attempt to pass objects but not in the manner in which I am trying to..Are you able to pass whole objects after they have been have been selected in a tableview to another view controller to present all data related to that object or are you only able to pass information from that object to the next viewcontroller? I have examples of prepareforsegue and perform segue before not sure what else I am missing but I am currently not able to pass any information between the tableview and the viewcontroller.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "decktoRecord") {
var detailVC: StatWidgetViewController = segue.destinationViewController as! StatWidgetViewController
detailVC.deckRecord = decktoPass
}
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let indexPath = tableView.indexPathForSelectedRow()
let selectedCell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell?
self.performSegueWithIdentifier("decktoRecord", sender: indexPath);
}
decktoPass is just a variable that contains the type of data entity that is the primary entity of the object.
A little confused by what you're asking but from what I understand, once the user clicks on a cell you want to segue to another view controller where they can edit the the details?
To add an exception breakpoint, open up your left panel with all your files/viewcontrollers, at the very top of it should be a small panel with a few icons, the first one is a folder, click on the second last one (the one that looks like a tag)
click on the plus in the bottom right and click add exception breakpoint, this should let you know where the problem in your code is occurring
Okay to edit the details in another View controller start by preparing the segue from the original view controller
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showTaskDetail" {
let detailVC: TaskDetailViewController = segue.destinationViewController as! TaskDetailViewController
let indexPath = self.tableView.indexPathForSelectedRow()
let thisTask = fetchedResultsController.objectAtIndexPath(indexPath!) as! TaskModel
detailVC.detailTaskModel = thisTask
detailVC.delegate = self
}
else if segue.identifier == "showTaskAdd" {
let addTaskVC:AddTaskViewController = segue.destinationViewController as! AddTaskViewController
addTaskVC.delegate = self
}
}
okay so like the code is showing above, I have a segue called showTaskDetail which shows the details of whatever it is, in my case its a simple task. You said you want to edit this information in another view controller when a user clicks on the row, well you need to be able to get this information in the other view controller.
So create a variable in the other viewcontroller that will hold these values, for me i called it detailTaskModel
var detailTaskModel: TaskModel!
Incase you're confused about what TaskModel is, I'm using CoreData to store my data, and TaskModel is a NSMangedObject class.
let detailVC: TaskDetailViewController = segue.destinationViewController as! TaskDetailViewController
this line you're just specifying what your other view controller is, replace TaskDetailViewController with your swift class.
let detailVC: TaskDetailViewController = segue.destinationViewController as! TaskDetailViewController
this line fetches the data from the row selected
Now you should be able to pass your information into the other view controller and edit it using the detailTaskModel, do you need help with that as well?

How do I pass a value from my SplitView controller to a map?

So I have a SplitView controller and the cells have cities and states (ex: Dalllas, TX, etc) when I select a cell I know how to go to a detail view using a segue. But, how do I send data another UIViewController containing a map?
After I’ve created my segue my code associated with the SplitView looks like this:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let cell:UITableViewCell = sender as! UITableViewCell
let destinationViewController:ViewController = segue.destinationViewController as! ViewController
// “cell.textLable” is where the value is passed from the SplitView
if let text = cell.textLabel!.text {
let incedent = LocationIncedent(sName: text)
destinationViewController.detailString = "Lat:" + String(stringInterpolationSegment: incedent.incLat) + " Long:" + String(stringInterpolationSegment: incedent.incLong)
DestinationViewController is where the label accepts displays the value. However, how do I get the values sent to a map instead of a label. Moreover, I need to pass latitude and longitude coordinates to a CLLocationCoordinate2D method.
Thanks
You create a property on the destinationViewController for each object you want to pass and assign this property in the segue method.
In your destinationViewController's viewDidLoad() you can user the data signed to these properties to populate a MKMapView...

Segue not working

I am making an iOS app in swift where I have a tableView with cells, what I want is to transit to another view controller when I click on the cell. Here is my code block for the segue source.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "selectedEvent"{
let cellIndex = tableView.indexPathForSelectedRow();
let tempIndex = cellIndex?.row
let name = eventsManager.createdEvents[tempIndex!].name
let address = eventsManager.createdEvents[tempIndex!].address
let latD = eventsManager.createdEvents[tempIndex!].eventLat
let lonD = eventsManager.createdEvents[tempIndex!].eventLon
let coords = CLLocationCoordinate2DMake(latD, lonD)
}
println("segue fired")
}
Here is the code in the segue destination.
#IBAction func showOnMap(segue: UIStoryboardSegue){
println("segue check")
self.performSegueWithIdentifier("selectedEvent", sender: self)
let showEventController = segue.sourceViewController as EventListViewController
let focusAddress = showEventController.address
let position = showEventController.coords
let name = showEventController.name
var marker = GMSMarker(position: position!)
println("is marker working? I hope so")
marker.title = name
marker.map = self.mapView
}
The println statements are to check if the segue is firing and the first statement "segue fired" prints on the console, and the view in the simulator switches to the destination viewController. Unfortunately, the 2nd part of the code does not execute and I am having trouble figuring out why.
The println("segue check") line will only print if the code inside IBAction is triggered by an event. Make sure IBAction is connected to the proper object in your view controller's view.
Why are you calling self.performSegueWithIdentifier("selectedEvent", sender: self) at the destination view controller's showOnMap function and then appear to be getting an instance of the view controller where you came from?
If you want to save data in your segue destination, you should first define variables in your destination's view controller and then save it at the destination in your prepareForSegue above. Something like this:
if segue.identifier == "selectedEvent"{
...
let coords = CLLocationCoordinate2DMake(latD, lonD)
...
let myDestVC = segue.destinationViewController as MyDestinationViewController
let myDestVC.coords = coords
...
}
Once you've got all your data saved, you can use them where ever you want in your destination's view controller. If you want to use them immediately, you can do so by overriding viewDidLoad viewWillAppear or viewDidAppear,